]> Creatis software - bbtk.git/blob - kernel/src/bbtkConfigurationFile.cxx
dbcc49becd70040a299d5e330eb0423962004a46
[bbtk.git] / kernel / src / bbtkConfigurationFile.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkConfigurationFile.cxx,v $
4   Language:  C++
5   Date:      $Date: 2008/12/10 10:00:36 $
6   Version:   $Revision: 1.24 $
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           return name;
377   }
378           
379 /*        
380     /// \todo : Think to delete it!
381     char *buf = (char *)malloc(512);
382         if (!buf) 
383         {
384                 bbtkError("Could not allocate 512 bytes !");
385         }
386     char *slash;
387     
388 #if defined(WIN32)
389     GetModuleFileName(NULL, buf, 511);
390     slash = strrchr(buf, '\\');
391     if (slash)
392       {
393         *slash = 0;
394       }
395 #endif 
396           
397
398 #if defined(__GNUC__)
399     int res;
400     res = readlink("/proc/self/exe", buf, 512);
401     if (res == -1)
402         {
403             free(buf);
404                 
405         }
406     buf[res] = 0;
407     slash = strrchr(buf, '/');
408     if (slash)
409       {
410         *slash = 0;
411       }
412 #endif
413     std::string ret(buf);
414     free(buf);
415     return ret;
416   }
417   //=========================================================================
418 */
419
420   //=========================================================================
421   void ConfigurationFile::InstallPath ()
422   {
423     
424     /*--------------------------------------------------
425       New policy for bbtk_config.xml :
426       
427       if bbtk_config.xml found in current directory (user is an aware user!)
428       use it!
429       
430       else if bbtk_config.xml found in HOME/.bbtk (user already worked with it)
431       use it!
432       
433       else if bbtk_config.xml.tmp found in /usr/local/bin or c:\\Program Files\\BBTK\\bin
434       copy it as .bbtk/bbtk_config.xml
435       
436       else (nothing installed)
437       create a minimum version in HOME/.bbtk
438       ----------------------------------------------------*/
439     
440     
441     // -----------------------------------------------------------------
442 #if defined(__GNUC__)
443     
444     // ------------------ create some usefull strings ----------------
445     // installed bbtk_path
446     char bbtk_path[100];
447     strcpy(bbtk_path, "/usr/local/bin");
448     
449     // rootDirectory
450     char rootDirectory[200];
451     sprintf( rootDirectory,  "%s/.bbtk", getenv("HOME"));
452     
453     // configPath
454     char configPath[200];
455     sprintf(configPath, "%s/bbtk_config.xml",rootDirectory);
456     
457     // makeDir
458     char makeDir[250];
459     sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
460     
461     // configXmlTmp
462     char configXmlTmp[250]; 
463     sprintf(configXmlTmp, "%s/bbtk_config.xml.tmp", bbtk_path);
464     
465     // copyFile
466     char copyFile[250];
467     
468     if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found (not installed)
469       {  
470         if (!Utilities::FileExists(rootDirectory)) // .bbtk not found
471           {
472             system(makeDir);  // create .bbtk
473           }
474         
475         // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
476         CreateConfigXML( rootDirectory );// create .bbtk
477       }
478     else
479       {
480         sprintf(copyFile,"cp %s  %s/bbtk_config.xml ",configXmlTmp,rootDirectory );
481         if (!Utilities::FileExists(rootDirectory))
482           {
483             //std::cout << "makeDir[" << makeDir << "]" << std::endl;
484             system(makeDir);
485           }
486         
487         if (!Utilities::FileExists(configPath))
488           {
489             system(copyFile);
490           }
491       }
492     return;
493     
494     // ------------------------------------------------------------------
495 #elif defined(WIN32)
496     
497     
498     // installed bbtk_path
499     char bbtk_path[100];
500     strcpy(bbtk_path, "\"c:\\Program Files\\BBTK\\bin\"");
501     char bbtk_path2[100];
502     strcpy(bbtk_path2, "c:\\Program Files\\BBTK\\bin");
503     
504     // rootDirectory
505     char rootDirectory[200];  
506     sprintf(rootDirectory, "%s\\.bbtk",getenv("USERPROFILE"));
507     //  std::cout << "[" << rootDirectory << "]" << std::endl;
508     
509     // configPath
510     char configPath[200];
511     sprintf(configPath, "%s\\bbtk_config.xml",rootDirectory);
512     
513     // makeDir
514     char makeDir[250];
515     sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
516     
517     // configXmlTmp
518     char configXmlTmp[250]; 
519     sprintf(configXmlTmp, "%s\\bbtk_config.xml.tmp", bbtk_path2);
520     
521     // copyFile
522     char copyFile[250];
523     
524     if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found
525       {
526         if (!Utilities::FileExists(rootDirectory)) // .bbtk not found
527           {
528             system(makeDir);  // create .bbtk
529           }
530         
531         // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
532         CreateConfigXML( rootDirectory );// create .bbtk
533         return;
534       }  
535     
536     sprintf(copyFile,"copy %s\\bbtk_config.xml.tmp \"%s\"\\bbtk_config.xml ",bbtk_path,rootDirectory );
537     
538     int attribs = GetFileAttributes (rootDirectory);
539     bbtkMessage("Config",1,std::hex << attribs << " " << FILE_ATTRIBUTE_DIRECTORY << std::endl);
540     if ( attribs != 0xFFFFFFFF)
541       {
542         if ((attribs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) /// \TODO : check !
543           {
544             if ( GetFileAttributes( configPath ) == 0xFFFFFFFF)
545               {
546                 system(copyFile);  
547               } 
548           }
549       } 
550     else 
551       {
552         system(makeDir);
553         system(copyFile); 
554       }    
555     return;  
556     // ------------------------------------------------------------------    
557 #else
558 /// \todo  ConfigurationFile::InstallPath() : exit when for not WIN32 and not__GNUC__
559
560   return;    
561 #endif
562
563 }
564   //=========================================================================
565
566
567
568   //=========================================================================
569   // Gets the list of directories holding bb scripts, packages, dll, ... from the xml file
570   //      bbtk_config.xml
571   
572   void ConfigurationFile::Read(const std::string& filename)
573   {
574     
575     bbtkDebugMessage("Config",1,"ConfigurationFile::Read(" <<filename << ")" << std::endl);
576     
577     mConfig_xml_full_path = filename;
578     XMLResults* res = new XMLResults;
579     XMLNode BB = XMLNode::parseFile((XMLCSTR)filename.c_str(),(XMLCSTR)"config",res);
580     
581     if ( res->error != eXMLErrorNone ) 
582       {
583         std::string mess = GetErrorMessage(res,filename);
584         delete res;
585         bbtkDebugMessage("Config",1,mess<< std::endl);
586         bbtkError(mess);
587       }
588     delete res;
589     
590     bbtkDebugMessage("Config",1,"OK" << std::endl);
591   
592     int i,j;
593     
594     // Description
595     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"description"); i++) 
596       {
597         std::string val;
598         GetTextOrClear(BB.getChildNode((XMLCSTR)"description",&j),val);
599         mDescription += val;
600       }    
601     
602     // Url
603     if( BB.nChildNode((XMLCSTR)"url") ) 
604       GetTextOrClear(BB.getChildNode((XMLCSTR)"url"),mUrl);
605     
606     // Data_Path
607     if( BB.nChildNode((XMLCSTR)"data_path") ) 
608       GetTextOrClear(BB.getChildNode((XMLCSTR)"data_path"),mData_path);
609     
610     // install_path
611     //  if( BB.nChildNode((XMLCSTR)"install_path") )
612     //   GetTextOrClear(BB.getChildNode((XMLCSTR)"install_path"),mInstall_path);
613     
614     // add user bbs paths
615     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"bbs_path"); i++) 
616       {
617         std::string val;
618         GetTextOrClear(BB.getChildNode((XMLCSTR)"bbs_path",&j),val);
619         mBbs_paths.push_back(val);
620       }
621     
622     // package_paths
623     
624     // add user package path
625     for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"package_path"); i++) 
626       {
627         std::string val;
628         GetTextOrClear(BB.getChildNode((XMLCSTR)"package_path",&j),val);
629         mPackage_paths.push_back(val);
630       }
631     
632     // default_temp_dir
633     if( BB.nChildNode((XMLCSTR)"default_temp_dir") ) 
634       GetTextOrClear(BB.getChildNode((XMLCSTR)"default_temp_dir"),mDefault_temp_dir);
635     
636     if ( mDefault_temp_dir == "$") // no value found in config_xml
637       {
638         size_t pos = mConfig_xml_full_path.find("bbtk_config.xml");
639         mDefault_temp_dir = mConfig_xml_full_path.substr (0,pos); 
640       }    
641
642     GetHelp(2);
643   }
644   //=========================================================================
645   
646   //=========================================================================
647   bool ConfigurationFile::AddPackagePathsAndWrite( const std::string& path )
648   {
649     bbtkDebugMessageInc("Config",9,
650                         "ConfigurationFile::AddPackagePathsAndWrite("
651                         <<path<<")"<<std::endl);
652     
653      XMLResults* res = new XMLResults;
654     XMLNode BB = 
655       XMLNode::parseFile((XMLCSTR)Get_config_xml_full_path().c_str(),
656                          (XMLCSTR)"config",res);
657     
658     if ( res->error != eXMLErrorNone ) 
659       {
660         std::string mess = GetErrorMessage(res,Get_config_xml_full_path());
661         delete res;
662         bbtkDebugMessage("Config",1,mess<< std::endl);
663         bbtkError(mess);
664       }
665    delete res;
666
667 #ifdef _WIN32
668     std::string bbs_path = path + "/bbs";
669 #else
670     std::string bbs_path = path + "/share/bbtk/bbs" ;
671 #endif
672     XMLNode BBSPATH = BB.addChild((XMLCSTR)"bbs_path");
673     BBSPATH.addText((XMLCSTR)bbs_path.c_str());
674     Utilities::replace(bbs_path, INVALID_FILE_SEPARATOR, VALID_FILE_SEPARATOR);
675     mBbs_paths.push_back(bbs_path);
676  
677 #ifdef _WIN32
678     std::string pack_path = path + "/bin";
679 #else
680     std::string pack_path = path ;
681 #endif
682     XMLNode PACKPATH = BB.addChild((XMLCSTR)"package_path");
683     PACKPATH.addText((XMLCSTR)pack_path.c_str());
684     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
685     mPackage_paths.push_back(pack_path);
686
687 #ifdef _WIN32
688     pack_path = path + "/Debug";
689     PACKPATH = BB.addChild((XMLCSTR)"package_path");
690     PACKPATH.addText((XMLCSTR)pack_path.c_str());
691     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
692     mPackage_paths.push_back(pack_path);
693     pack_path = path + "/Release";
694     PACKPATH = BB.addChild((XMLCSTR)"package_path");
695     PACKPATH.addText((XMLCSTR)pack_path.c_str());
696     Utilities::replace(pack_path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
697     mPackage_paths.push_back(pack_path);
698 #endif
699
700
701     XMLError err = BB.writeToFile((XMLCSTR)Get_config_xml_full_path().c_str());
702     if ( err != eXMLErrorNone ) 
703       {
704         std::string mess = GetErrorMessage(res,Get_config_xml_full_path());
705         bbtkDebugMessage("Config",1,mess<< std::endl);
706         bbtkError(mess);
707       }
708
709     return true;
710   }
711   //=========================================================================
712
713   //=========================================================================
714   void ConfigurationFile::GetHelp(int level) const
715   {
716     bbtkDebugMessageInc("Config",9,"ConfigurationFile::GetHelp("<<level
717                         <<")"<<std::endl);
718     
719     const std::string config_xml_full_path      = Get_config_xml_full_path();    
720     const std::string description               = Get_description();
721     const std::string url                       = Get_doc_path();
722     const std::string data_path                 = Get_data_path();
723     const std::string default_temp_dir          = Get_default_temp_dir();    
724     const std::string file_separator            = Get_file_separator();    
725     const std::vector<std::string>bbs_paths     = Get_bbs_paths();
726     const std::vector<std::string>package_paths = Get_package_paths();
727     
728     bbtkMessage("Help",level, "============="   << std::endl);           
729     bbtkMessage("Help",level, "Configuration"   << std::endl);
730     bbtkMessage("Help",level, "============="   << std::endl);
731     bbtkMessage("Help",level, "bbtk_config.xml    : [" << config_xml_full_path  << "]" << std::endl); 
732     bbtkMessage("Help",level, "Documentation Path : [" << url             << "]" << std::endl);
733     bbtkMessage("Help",level, "Data Path          : [" << data_path       << "]" << std::endl);
734     bbtkMessage("Help",level, "Temp Directory     : [" << default_temp_dir << "]" << std::endl);
735     bbtkMessage("Help",level, "File Separator     : [" << file_separator  << "]" << std::endl);
736
737     std::vector<std::string>::const_iterator i;
738            
739     bbtkMessage("Help",level, "BBS Paths   " << std::endl);     
740     for (i = bbs_paths.begin(); i!=bbs_paths.end(); ++i )
741     {
742       bbtkMessage("Help",level,"--- ["<<*i<<"]"<<std::endl);
743     }    
744     
745     bbtkMessage("Help",level, "PACKAGE Paths : " << std::endl);     
746     for (i = package_paths.begin(); i!=package_paths.end(); ++i )
747     {
748       bbtkMessage("Help",level,"--- ["<<*i<<"]"<<std::endl);
749     }
750
751     bbtkDebugDecTab("Config",9);
752   }
753   //=========================================================================
754
755
756 } // namespace bbtk