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