]> Creatis software - bbtk.git/blob - kernel/src/bbtkConfigurationFile.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkConfigurationFile.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkConfigurationFile.cxx,v $
4   Language:  C++
5   Date:      $Date: 2008/11/21 15:26:44 $
6   Version:   $Revision: 1.22 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *\file
33  *\brief Class bbtk::ConfigurationFile
34  */
35
36 #include "bbtkConfigurationFile.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkXML.h"
39 #include "bbtkUtilities.h"
40
41 #if defined(WIN32)
42 # include <direct.h> // for getcwd
43 # include <windows.h>
44 #endif
45
46 #if defined(MACOSX) // assume this is OSX 
47 # include <sys/param.h>
48 # include <mach-o/dyld.h> // _NSGetExecutablePath : must add -framework CoreFoundation to link line 
49 # include <string.h>
50 # ifndef PATH_MAX
51 #  define PATH_MAX MAXPATHLEN
52 # endif
53 #endif // MACOSX
54
55 #ifndef PATH_MAX // If not defined yet : do it 
56 #  define PATH_MAX 2048
57 #endif
58
59
60 namespace bbtk
61 {
62
63   //====================================================================
64   /// Constructor
65   ConfigurationFile::ConfigurationFile()
66   {
67
68         mFile_separator = VALID_FILE_SEPARATOR;
69     
70     // ==> Set system paths 
71     mBin_path = GetExecutablePath();
72 //EED    mInstall_path = mBin_path + mFile_separator + "..";
73 #ifdef MACOSX
74           mInstall_path = mBin_path + "/../../../..";
75 #else
76           mInstall_path = mBin_path + "/..";
77 #endif
78           // The relative path to the doc folder (=BBTK_DOC_REL_PATH)
79     mDoc_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH);
80     // The path to the doc folder (=mInstall_path+"/"+mDoc_rel_path)
81 //EED    mDoc_path = mInstall_path + mFile_separator + mDoc_rel_path;
82     mDoc_path = mInstall_path + "/" + mDoc_rel_path;
83     // The relative path to the doc folder (=BBTK_BBS_REL_PATH)
84     mBbs_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_BBS_REL_PATH);
85     // The path to the bbs folder (=mInstall_path+"/"+mBbs_rel_path)
86 //EED    mBbs_path = mInstall_path + mFile_separator + mBbs_rel_path;
87     mBbs_path = mInstall_path + "/" + mBbs_rel_path;
88     // The relative path to the rsc folder (=BBTK_RSC_REL_PATH)
89     //   mRsc_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_RSC_REL_PATH);
90     // The path to the rsc folder (=mInstall_path+"/"+mRsc_rel_path)
91     //   mRsc_path = mInstall_path + mFile_separator + mRsc_rel_path;
92     // The path to the bbtk data folder 
93     // Initialized to mInstall_path+"/"+BBTK_DATA_REL_PATH
94     // But can be overriden by value read from bbtk_config.xml
95 //EED    mData_path = mInstall_path + mFile_separator + BBTK_STRINGIFY_SYMBOL(BBTK_DATA_REL_PATH);
96     mData_path = mInstall_path + "/" + BBTK_STRINGIFY_SYMBOL(BBTK_DATA_REL_PATH);
97
98         Utilities::replace( mBin_path           , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
99         Utilities::replace( mInstall_path       , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
100         Utilities::replace( mDoc_rel_path       , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
101         Utilities::replace( mDoc_path           , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
102         Utilities::replace( mBbs_path           , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
103         Utilities::replace( mData_path          , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
104
105     bbtkMessage("Config",1," ==> bin    : '"<<mBin_path<<"'"<<std::endl);
106     bbtkMessage("Config",1," ==> prefix : '"<<mInstall_path<<"'"<<std::endl);
107     bbtkMessage("Config",1," ==> doc    : '"<<mDoc_path<<"'"<<std::endl);
108     bbtkMessage("Config",1," ==> bbs    : '"<<mBbs_path<<"'"<<std::endl);
109     bbtkMessage("Config",1," ==> data   : '"<<mData_path<<"'"<<std::endl);
110
111
112
113     
114     // bbs_paths
115     // always add "." (current working directory) at the begining
116         mBbs_paths.push_back( "." ); 
117     // add system bbs path 
118     mBbs_paths.push_back(mBbs_path);
119     // add toolsbbtk/appli 
120 //EED    std::string toolsappli_rel_path(mFile_separator);
121     std::string toolsappli_rel_path("/");
122 //EED    toolsappli_rel_path +=  "toolsbbtk" + mFile_separator + "appli";
123     toolsappli_rel_path +=  "toolsbbtk/appli";
124     //
125     //-----------------------------------------------------------
126     // LG : REMOVE BUGGY PATH WITH include *:
127     // 
128     //    mBbs_paths.push_back(mBbs_path + toolsappli_rel_path);
129     //-----------------------------------------------------------
130     int iStrVec,sizeStrVec;
131     
132     sizeStrVec = mBbs_paths.size();
133     for (iStrVec=0;iStrVec<sizeStrVec;iStrVec++){
134       Utilities::replace( mBbs_paths[iStrVec] , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
135     }
136
137     
138     // always add "." (current working directory) at the begining
139     mPackage_paths.push_back(".");   
140     // add system bin path (for build tree / standalone folder install)
141     mPackage_paths.push_back(mBin_path);
142     // add system lib path (for install tree)
143 //EED    mPackage_paths.push_back(mInstall_path + mFile_separator + "lib");
144     mPackage_paths.push_back(mInstall_path + "/lib");
145 #ifdef WIN32
146     // add bin/Debug bin/Release paths (for build/install tree)
147 //EED    mPackage_paths.push_back(mBin_path + mFile_separator + "Debug");
148     mPackage_paths.push_back(mBin_path + "/Debug");
149 //EED    mPackage_paths.push_back(mBin_path + mFile_separator + "Release");
150     mPackage_paths.push_back(mBin_path + "/Release");
151 #endif
152
153         sizeStrVec = mPackage_paths.size();
154         for (iStrVec=0;iStrVec<sizeStrVec;iStrVec++){
155                 Utilities::replace( mPackage_paths[iStrVec] , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
156         }
157
158
159
160     GetHelp(2);
161    
162     // ==> First we look for bbtk_config.xml in "."
163     char buf[2048];
164     const char *currentDir = getcwd(buf, 2048);
165     
166     if( !currentDir )
167       {
168         std::cerr << "Path was too long to fit on 2048 bytes ?!?" << std::endl;
169         // \todo : what else?
170         // How abort a constructor and warn the caller function?
171         // LG : throw an exception 
172       }
173     
174 //    std::string configXmlFullPathName = currentDir + mFile_separator + "bbtk_config.xml";
175     std::string configXmlFullPathName = currentDir ;
176                 configXmlFullPathName += "/bbtk_config.xml";
177         Utilities::replace( configXmlFullPathName , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
178
179     if ( Utilities::FileExists( configXmlFullPathName ))
180       {
181         bbtkMessage("Config",1, "ConfigurationFile : [" << configXmlFullPathName << 
182                     "] found in current directory" << std::endl); 
183         //Read(configXmlFullPathName.c_str());
184         // traiter le fichier local     
185       }
186     
187     // ==> Then we look for bbtk_config.xml in ".bbtk"
188     else 
189       {
190         configXmlFullPathName = Utilities::MakeUserSettingsFullFileName("bbtk_config.xml");
191         if (!Utilities::FileExists( configXmlFullPathName ))
192           {         
193             // ==> Nothing found, we create bbtk_config.xml in ".bbtk"
194             InstallPath ();
195           }
196       }
197     
198     // In any case, deal with bbtk_config.xml!
199     Read(configXmlFullPathName.c_str());
200   }
201   //=========================================================================
202
203   //=========================================================================
204   /// Destructor
205   ConfigurationFile::~ConfigurationFile()
206   {
207   }
208   //=========================================================================
209   
210
211
212
213   //=========================================================================
214   void ConfigurationFile::CreateConfigXML( char *rootDirectory )
215   {
216     FILE *fp;
217     char configXml[250];
218     sprintf (configXml , "%s/bbtk_config.xml", rootDirectory);
219     bbtkDebugMessage("Config",1, "in CreateConfigXML[" << configXml << "]" << std::endl);
220     fp = fopen (configXml, "w");
221     fprintf(fp, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
222     fprintf(fp, "<config>\n");
223     fprintf(fp, "   <bbs_path>     </bbs_path>\n");
224     fprintf(fp, "   <package_path> </package_path>\n");
225     fprintf(fp, "   <default_temp_dir> $ </default_temp_dir>\n");    
226     fprintf(fp, "</config>\n");
227     fclose(fp);
228   }
229   //=========================================================================  
230
231         
232         
233         //=========================================================================  
234         // From http://www.fltk.org/newsgroups.php?gfltk.general+v:22083
235         //
236         int get_app_path (char *pname, size_t pathsize)
237         {
238 #ifdef LINUX
239         /* Oddly, the readlink(2) man page says no NULL is appended. */
240         /* So you have to do it yourself, based on the return value: */
241         pathsize --; /* Preserve a space to add the trailing NULL */
242         long result = readlink("/proc/self/exe", pname, pathsize);
243         if (result > 0)
244         {
245                         pname[result] = 0; /* add the #@!%ing NULL */
246                         
247                         if ((access(pname, 0) == 0))
248                                 return 0; /* file exists, return OK */
249                         /*else name doesn't seem to exist, return FAIL (falls
250                          through) */
251         }
252 #endif /* LINUX */
253                 
254 #ifdef WIN32
255         long result = GetModuleFileName(NULL, pname, pathsize);
256         if (result > 0)
257         {
258                         /* fix up the dir slashes... */
259                         int len = strlen(pname);
260                         int idx;
261                         for (idx = 0; idx < len; idx++)
262                         {
263                                 if (pname[idx] == '\\') pname[idx] = '/';
264                         }
265
266                         for (idx = len-1; idx >=0 ; idx--)
267                         {
268                                 if (pname[idx] == '/')
269                                 { 
270                                         pname[idx+1] = '\0';
271                                         idx = -1;
272                                 }
273                         }
274
275                         if ((access(pname, 0) == 0))
276                                 return 0; /* file exists, return OK */
277                         /*else name doesn't seem to exist, return FAIL (falls
278                          through) */
279         }
280 #endif /* WIN32 */
281                 
282 #ifdef SOLARIS
283         char *p = getexecname();
284         if (p)
285         {
286                         /* According to the Sun manpages, getexecname will
287                          "normally" return an */
288                         /* absolute path - BUT might not... AND that IF it is not,
289                          pre-pending */
290                         /* getcwd() will "usually" be the correct thing... Urgh!
291                          */
292                         
293                         /* check pathname is absolute (begins with a / ???) */
294                         if (p[0] == '/') /* assume this means we have an
295                          absolute path */
296                         {
297                                 strncpy(pname, p, pathsize);
298                                 if ((access(pname, 0) == 0))
299                                         return 0; /* file exists, return OK */
300                         }
301                         else /* if not, prepend getcwd() then check if file
302                          exists */
303                         {
304                                 getcwd(pname, pathsize);
305                                 long result = strlen(pname);
306                                 strncat(pname, "/", (pathsize - result));
307                                 result ++;
308                                 strncat(pname, p, (pathsize - result));
309                                 
310                                 if ((access(pname, 0) == 0))
311                                         return 0; /* file exists, return OK */
312                                 /*else name doesn't seem to exist, return FAIL
313                                  (falls through) */
314                         }
315         }
316 #endif /* SOLARIS */
317                 
318 #ifdef MACOSX /* assume this is OSX */
319                 /*
320                  from http://www.hmug.org/man/3/NSModule.html
321                  
322                  extern int _NSGetExecutablePath(char *buf, unsigned long
323                  *bufsize);
324                  
325                  _NSGetExecutablePath  copies  the  path  of the executable
326                  into the buffer and returns 0 if the path was successfully
327                  copied  in the provided buffer. If the buffer is not large
328                  enough, -1 is returned and the  expected  buffer  size  is
329                  copied  in  *bufsize.  Note that _NSGetExecutablePath will
330                  return "a path" to the executable not a "real path" to the
331                  executable.  That  is  the path may be a symbolic link and
332                  not the real file. And with  deep  directories  the  total
333                  bufsize needed could be more than MAXPATHLEN.
334                  */
335         int status = -1;
336         char *given_path = (char*)malloc(MAXPATHLEN * 2);
337         if (!given_path) return status;
338                 
339         uint32_t npathsize = MAXPATHLEN * 2;
340         long result = _NSGetExecutablePath(given_path, &npathsize);
341         if (result == 0)
342         { /* OK, we got something - now try and resolve the real path...
343                  */
344                         if (realpath(given_path, pname) != NULL)
345                         {
346                                 if ((access(pname, 0) == 0))
347                                         status = 0; /* file exists, return OK */
348                         }
349         }
350         free (given_path);
351         return status;
352 #endif /* MACOSX */
353                 
354         return -1; /* Path Lookup Failed */
355         } 
356         
357
358         
359   //=========================================================================
360   std::string ConfigurationFile::GetExecutablePath()
361   {
362           char name[PATH_MAX];
363           int err = get_app_path(name, PATH_MAX);
364           if (err) 
365           {
366                 bbtkError("Could not determine current executable path ?");  
367           }
368           
369           // remove the exe name
370           char *slash;          
371           slash = strrchr(name, VALID_FILE_SEPARATOR_CHAR);
372           if (slash)
373           {
374                   *slash = 0;
375           }
376 printf("EED ConfigurationFile::GetExecutablePath  %s\n",name);
377           return name;
378   }
379           
380 /*        
381     /// \todo : Think to delete it!
382     char *buf = (char *)malloc(512);
383         if (!buf) 
384         {
385                 bbtkError("Could not allocate 512 bytes !");
386         }
387     char *slash;
388     
389 #if defined(WIN32)
390     GetModuleFileName(NULL, buf, 511);
391     slash = strrchr(buf, '\\');
392     if (slash)
393       {
394         *slash = 0;
395       }
396 #endif 
397           
398
399 #if defined(__GNUC__)
400     int res;
401     res = readlink("/proc/self/exe", buf, 512);
402     if (res == -1)
403         {
404             free(buf);
405                 
406         }
407     buf[res] = 0;
408     slash = strrchr(buf, '/');
409     if (slash)
410       {
411         *slash = 0;
412       }
413 #endif
414     std::string ret(buf);
415     free(buf);
416     return ret;
417   }
418   //=========================================================================
419 */
420
421   //=========================================================================
422   void ConfigurationFile::InstallPath ()
423   {
424     
425     /*--------------------------------------------------
426       New policy for bbtk_config.xml :
427       
428       if bbtk_config.xml found in current directory (user is an aware user!)
429       use it!
430       
431       else if bbtk_config.xml found in HOME/.bbtk (user already worked with it)
432       use it!
433       
434       else if bbtk_config.xml.tmp found in /usr/local/bin or c:\\Program Files\\BBTK\\bin
435       copy it as .bbtk/bbtk_config.xml
436       
437       else (nothing installed)
438       create a minimum version in HOME/.bbtk
439       ----------------------------------------------------*/
440     
441     
442     // -----------------------------------------------------------------
443 #if defined(__GNUC__)
444     
445     // ------------------ create some usefull strings ----------------
446     // installed bbtk_path
447     char bbtk_path[100];
448     strcpy(bbtk_path, "/usr/local/bin");
449     
450     // rootDirectory
451     char rootDirectory[200];
452     sprintf( rootDirectory,  "%s/.bbtk", getenv("HOME"));
453     
454     // configPath
455     char configPath[200];
456     sprintf(configPath, "%s/bbtk_config.xml",rootDirectory);
457     
458     // makeDir
459     char makeDir[250];
460     sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
461     
462     // configXmlTmp
463     char configXmlTmp[250]; 
464     sprintf(configXmlTmp, "%s/bbtk_config.xml.tmp", bbtk_path);
465     
466     // copyFile
467     char copyFile[250];
468     
469     if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found (not installed)
470       {  
471         if (!Utilities::FileExists(rootDirectory)) // .bbtk not found
472           {
473             system(makeDir);  // create .bbtk
474           }
475         
476         // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
477         CreateConfigXML( rootDirectory );// create .bbtk
478       }
479     else
480       {
481         sprintf(copyFile,"cp %s  %s/bbtk_config.xml ",configXmlTmp,rootDirectory );
482         if (!Utilities::FileExists(rootDirectory))
483           {
484             //std::cout << "makeDir[" << makeDir << "]" << std::endl;
485             system(makeDir);
486           }
487         
488         if (!Utilities::FileExists(configPath))
489           {
490             system(copyFile);
491           }
492       }
493     return;
494     
495     // ------------------------------------------------------------------
496 #elif defined(WIN32)
497     
498     
499     // installed bbtk_path
500     char bbtk_path[100];
501     strcpy(bbtk_path, "\"c:\\Program Files\\BBTK\\bin\"");
502     char bbtk_path2[100];
503     strcpy(bbtk_path2, "c:\\Program Files\\BBTK\\bin");
504     
505     // rootDirectory
506     char rootDirectory[200];  
507     sprintf(rootDirectory, "%s\\.bbtk",getenv("USERPROFILE"));
508     //  std::cout << "[" << rootDirectory << "]" << std::endl;
509     
510     // configPath
511     char configPath[200];
512     sprintf(configPath, "%s\\bbtk_config.xml",rootDirectory);
513     
514     // makeDir
515     char makeDir[250];
516     sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
517     
518     // configXmlTmp
519     char configXmlTmp[250]; 
520     sprintf(configXmlTmp, "%s\\bbtk_config.xml.tmp", bbtk_path2);
521     
522     // copyFile
523     char copyFile[250];
524     
525     if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found
526       {
527         if (!Utilities::FileExists(rootDirectory)) // .bbtk not found
528           {
529             system(makeDir);  // create .bbtk
530           }
531         
532         // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
533         CreateConfigXML( rootDirectory );// create .bbtk
534         return;
535       }  
536     
537     sprintf(copyFile,"copy %s\\bbtk_config.xml.tmp \"%s\"\\bbtk_config.xml ",bbtk_path,rootDirectory );
538     
539     int attribs = GetFileAttributes (rootDirectory);
540     bbtkMessage("Config",1,std::hex << attribs << " " << FILE_ATTRIBUTE_DIRECTORY << std::endl);
541     if ( attribs != 0xFFFFFFFF)
542       {
543         if ((attribs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) /// \TODO : check !
544           {
545             if ( GetFileAttributes( configPath ) == 0xFFFFFFFF)
546               {
547                 system(copyFile);  
548               } 
549           }
550       } 
551     else 
552       {
553         system(makeDir);
554         system(copyFile); 
555       }    
556     return;  
557     // ------------------------------------------------------------------    
558 #else
559 /// \todo  ConfigurationFile::InstallPath() : exit when for not WIN32 and not__GNUC__
560
561   return;    
562 #endif
563
564 }
565   //=========================================================================
566
567
568
569   //=========================================================================
570   // Gets the list of directories holding bb scripts, packages, dll, ... from the xml file
571   //      bbtk_config.xml
572   
573   void ConfigurationFile::Read(const std::string& filename)
574   {
575     
576     bbtkDebugMessage("Config",1,"ConfigurationFile::Read(" <<filename << ")" << std::endl);
577     
578     mConfig_xml_full_path = filename;
579     XMLResults* res = new XMLResults;
580     XMLNode BB = XMLNode::parseFile((XMLCSTR)filename.c_str(),(XMLCSTR)"config",res);
581     
582     if ( res->error != eXMLErrorNone ) 
583       {
584         std::string mess = GetErrorMessage(res,filename);
585         delete res;
586         bbtkDebugMessage("Config",1,mess<< std::endl);
587         bbtkError(mess);
588       }
589     delete res;
590     
591     bbtkDebugMessage("Config",1,"OK" << std::endl);
592   
593     int i,j;
594     
595     // Description
596     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"description"); i++) 
597       {
598         std::string val;
599         GetTextOrClear(BB.getChildNode((XMLCSTR)"description",&j),val);
600         mDescription += val;
601       }    
602     
603     // Url
604     if( BB.nChildNode((XMLCSTR)"url") ) 
605       GetTextOrClear(BB.getChildNode((XMLCSTR)"url"),mUrl);
606     
607     // Data_Path
608     if( BB.nChildNode((XMLCSTR)"data_path") ) 
609       GetTextOrClear(BB.getChildNode((XMLCSTR)"data_path"),mData_path);
610     
611     // install_path
612     //  if( BB.nChildNode((XMLCSTR)"install_path") )
613     //   GetTextOrClear(BB.getChildNode((XMLCSTR)"install_path"),mInstall_path);
614     
615     // add user bbs paths
616     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"bbs_path"); i++) 
617       {
618         std::string val;
619         GetTextOrClear(BB.getChildNode((XMLCSTR)"bbs_path",&j),val);
620         mBbs_paths.push_back(val);
621       }
622     
623     // package_paths
624     
625     // add user package path
626     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"package_path"); i++) 
627       {
628         std::string val;
629         GetTextOrClear(BB.getChildNode((XMLCSTR)"package_path",&j),val);
630         mPackage_paths.push_back(val);
631       }
632     
633     // default_temp_dir
634     if( BB.nChildNode((XMLCSTR)"default_temp_dir") ) 
635       GetTextOrClear(BB.getChildNode((XMLCSTR)"default_temp_dir"),mDefault_temp_dir);
636     
637     if ( mDefault_temp_dir == "$") // no value found in config_xml
638       {
639         size_t pos = mConfig_xml_full_path.find("bbtk_config.xml");
640         mDefault_temp_dir = mConfig_xml_full_path.substr (0,pos); 
641       }    
642
643     GetHelp(2);
644   }
645   //=========================================================================
646   
647   //=========================================================================
648   bool ConfigurationFile::AddPackagePathsAndWrite( const std::string& path )
649   {
650     bbtkDebugMessageInc("Config",9,
651                         "ConfigurationFile::AddPackagePathsAndWrite("
652                         <<path<<")"<<std::endl);
653     
654      XMLResults* res = new XMLResults;
655     XMLNode BB = 
656       XMLNode::parseFile((XMLCSTR)Get_config_xml_full_path().c_str(),
657                          (XMLCSTR)"config",res);
658     
659     if ( res->error != eXMLErrorNone ) 
660       {
661         std::string mess = GetErrorMessage(res,Get_config_xml_full_path());
662         delete res;
663         bbtkDebugMessage("Config",1,mess<< std::endl);
664         bbtkError(mess);
665       }
666    delete res;
667
668 #ifdef _WIN32
669     std::string bbs_path = path + "/bbs";
670 #else
671     std::string bbs_path = path + "/share/bbtk/bbs" ;
672 #endif
673     XMLNode BBSPATH = BB.addChild((XMLCSTR)"bbs_path");
674     BBSPATH.addText((XMLCSTR)bbs_path.c_str());
675     Utilities::replace(bbs_path, INVALID_FILE_SEPARATOR, VALID_FILE_SEPARATOR);
676     mBbs_paths.push_back(bbs_path);
677  
678 #ifdef _WIN32
679     std::string pack_path = path + "/bin";
680 #else
681     std::string pack_path = path ;
682 #endif
683     XMLNode PACKPATH = BB.addChild((XMLCSTR)"package_path");
684     PACKPATH.addText((XMLCSTR)pack_path.c_str());
685     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
686     mPackage_paths.push_back(pack_path);
687
688 #ifdef _WIN32
689     pack_path = path + "/Debug";
690     PACKPATH = BB.addChild((XMLCSTR)"package_path");
691     PACKPATH.addText((XMLCSTR)pack_path.c_str());
692     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
693     mPackage_paths.push_back(pack_path);
694     pack_path = path + "/Release";
695     PACKPATH = BB.addChild((XMLCSTR)"package_path");
696     PACKPATH.addText((XMLCSTR)pack_path.c_str());
697     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
698     mPackage_paths.push_back(pack_path);
699 #endif
700
701
702     XMLError err = BB.writeToFile((XMLCSTR)Get_config_xml_full_path().c_str());
703     if ( err != eXMLErrorNone ) 
704       {
705         std::string mess = GetErrorMessage(res,Get_config_xml_full_path());
706         bbtkDebugMessage("Config",1,mess<< std::endl);
707         bbtkError(mess);
708       }
709
710     return true;
711   }
712   //=========================================================================
713
714   //=========================================================================
715   void ConfigurationFile::GetHelp(int level) const
716   {
717     bbtkDebugMessageInc("Config",9,"ConfigurationFile::GetHelp("<<level
718                         <<")"<<std::endl);
719     
720     const std::string config_xml_full_path      = Get_config_xml_full_path();    
721     const std::string description               = Get_description();
722     const std::string url                       = Get_doc_path();
723     const std::string data_path                 = Get_data_path();
724     const std::string default_temp_dir          = Get_default_temp_dir();    
725     const std::string file_separator            = Get_file_separator();    
726     const std::vector<std::string>bbs_paths     = Get_bbs_paths();
727     const std::vector<std::string>package_paths = Get_package_paths();
728     
729     bbtkMessage("Help",level, "============="   << std::endl);           
730     bbtkMessage("Help",level, "Configuration"   << std::endl);
731     bbtkMessage("Help",level, "============="   << std::endl);
732     bbtkMessage("Help",level, "bbtk_config.xml    : [" << config_xml_full_path  << "]" << std::endl); 
733     bbtkMessage("Help",level, "Documentation Path : [" << url             << "]" << std::endl);
734     bbtkMessage("Help",level, "Data Path          : [" << data_path       << "]" << std::endl);
735     bbtkMessage("Help",level, "Temp Directory     : [" << default_temp_dir << "]" << std::endl);
736     bbtkMessage("Help",level, "File Separator     : [" << file_separator  << "]" << std::endl);
737
738     std::vector<std::string>::const_iterator i;
739            
740     bbtkMessage("Help",level, "BBS Paths   " << std::endl);     
741     for (i = bbs_paths.begin(); i!=bbs_paths.end(); ++i )
742     {
743       bbtkMessage("Help",level,"--- ["<<*i<<"]"<<std::endl);
744     }    
745     
746     bbtkMessage("Help",level, "PACKAGE Paths : " << std::endl);     
747     for (i = package_paths.begin(); i!=package_paths.end(); ++i )
748     {
749       bbtkMessage("Help",level,"--- ["<<*i<<"]"<<std::endl);
750     }
751
752     bbtkDebugDecTab("Config",9);
753   }
754   //=========================================================================
755
756
757 } // namespace bbtk