]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
avoid warning
[bbtk.git] / kernel / src / bbtkPackage.cxx
1
2 /*=========================================================================                                                                               
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/10/17 08:21:44 $
7   Version:   $Revision: 1.23 $
8 =========================================================================*/
9
10 /* ---------------------------------------------------------------------
11
12 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
13 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 *
15 *  This software is governed by the CeCILL-B license under French law and 
16 *  abiding by the rules of distribution of free software. You can  use, 
17 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
18 *  license as circulated by CEA, CNRS and INRIA at the following URL 
19 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
20 *  or in the file LICENSE.txt.
21 *
22 *  As a counterpart to the access to the source code and  rights to copy,
23 *  modify and redistribute granted by the license, users are provided only
24 *  with a limited warranty  and the software's author,  the holder of the
25 *  economic rights,  and the successive licensors  have only  limited
26 *  liability. 
27 *
28 *  The fact that you are presently reading this means that you have had
29 *  knowledge of the CeCILL-B license and that you accept its terms.
30 * ------------------------------------------------------------------------ */                                                                         
31
32 /**
33  *\file
34  *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
35  */
36 #include "bbtkPackage.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkConfigurationFile.h"
39 #include <fstream>
40 #include <time.h>
41 #include "bbtkUtilities.h"
42
43 namespace bbtk
44 {
45   
46
47
48   //==========================================================================
49   /// Creates a new package
50   Package::Pointer Package::New(const std::string& name,
51                                 const std::string& author,
52                                 const std::string& description,
53                                 const std::string& version,
54                                 const std::string& BBTKVersion) 
55   {
56     bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
57                      <<bbtkendl);
58     Package::Pointer p = MakePointer(new Package(name,
59                                                author,
60                                                description,
61                                                version,
62                                                BBTKVersion));
63     bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
64                      <<bbtkendl);
65     return p;
66   }
67   //==========================================================================
68
69   //==========================================================================
70   /// Ctor with the name of the package
71   Package::Package(const std::string& name,
72                    const std::string& author,
73                    const std::string& description,
74                    const std::string& version,
75                    const std::string& BBTKVersion) 
76     :
77     mDynamicLibraryHandler(0),
78     mName(name),
79     mAuthor(author),
80     mDescription(description),
81     mVersion(version)
82   {
83     bbtkDebugMessage("object",2,"==> Package::Package('"<<name<<"',...)"
84                      <<bbtkendl);
85     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
86     char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
87     std::string url = default_doc_dir; 
88     if (c != '/' && c !='\\') url = url + "/";
89     url = url +  "temp_dir/" + name + "/index.html";    
90     
91     SetDocURL(url);
92     SetDocRelativeURL("Relative url not set");
93
94     /*
95     std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
96     relurl += "/packages/"+name+"/bbdoc/index.html";
97     std::string url = ConfigurationFile::GetInstance().Get_url()
98       + relurl; 
99     SetDocURL(url);
100     SetDocRelativeURL(relurl);   
101     */
102
103     //    std::cout  << "   url=["<<url<<"]"<<std::endl;
104     //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
105     bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
106                      <<bbtkendl);
107
108   }
109   //==========================================================================
110
111
112
113   //==========================================================================
114   /// Dtor
115   Package::~Package()
116   {
117     bbtkDebugMessage("object",2,"==> Package::~Package(\""<<mName<<"\")"<<bbtkendl);
118     bbtkDebugMessage("object",2,"<== Package::~Package(\""<<mName<<"\")"<<bbtkendl);
119   }
120   //==========================================================================
121
122
123   //==========================================================================
124   void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
125                                                 const std::string& descname)
126   {
127     // Try to release descriptor
128     std::string packname = pack.lock()->GetName();
129
130     bbtkDebugMessage("package",5,"--- Releasing descriptor '"
131                      <<packname<<"::"<<descname<<"'"<<bbtkendl);
132
133
134     Package::BlackBoxMapType::iterator desc = 
135       pack.lock()->GetBlackBoxMap().find(descname);
136     if (desc ==  pack.lock()->GetBlackBoxMap().end())
137       {
138         bbtkDebugMessage("package",5,
139                          "    Descriptor has already been released"
140                          <<bbtkendl);
141         return;
142       }
143     //    bbtkDebugMessage("package",3,
144     //               "    Trying unreferencing it ... "<<std::endl);
145     BlackBoxDescriptor::WeakPointer pdesc = desc->second;
146     desc->second.reset();
147     // if it is dead : remove it 
148     if (pdesc.expired()) 
149       {
150         bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
151         if (pack.expired()) 
152           {
153             bbtkDebugMessage("package",2,
154                              "     ... and caused its package death"
155                              <<bbtkendl);
156             return;
157           }
158         desc = pack.lock()->GetBlackBoxMap().find(descname);
159         if (desc !=  pack.lock()->GetBlackBoxMap().end())
160           pack.lock()->GetBlackBoxMap().erase(desc);
161       }
162     else 
163       {
164         bbtkDebugMessage("package",5,"    ... Descriptor still alive ("
165                          <<pdesc.use_count()<<" refs)"
166                          <<bbtkendl);
167         pack.lock()->GetBlackBoxMap()[descname] = pdesc.lock();
168       }
169   }
170   //==========================================================================
171
172
173   //==========================================================================
174   /// Release
175   void Package::Release(Package::WeakPointer pack)
176   {
177     std::string packname = pack.lock()->mName;
178     bbtkDebugMessage("package",1,"==> Package::Release('"<<
179                      packname<<"')"<<bbtkendl);
180
181     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
182     long ndesc = pack.lock()->GetBlackBoxMap().size();
183     long nrefs = pack.use_count();
184
185     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
186                      <<ndesc<<" descr / dyn="
187                      <<dyn<<std::endl);
188
189     // A package is "free" from any external reference iff :
190     // i) It is not dynamically loaded and nrefs == ndesc 
191     // (each desc references its package) or
192     // ii) It is dynamically loaded and nrefs == ndesc + 1
193     // (A dynamic library holds a static pointer on the package it contains
194     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
195     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
196     if (nrefs == ndesc + dyn) 
197       {
198         bbtkDebugMessage("package",5,
199                          " -> No more external ref : checking descriptors"
200                          <<bbtkendl);
201         // We must take care that removing refs on descriptors 
202         // can lead to their deletion which can in turn unref 
203         // internal boxes which can release their descriptors hence 
204         // call Package::ReleaseBlackBoxDescriptor 
205         // As a consequence during descriptors release :
206         // 1) The map can change dynamically : we cannot iterate over it 
207         //    as any iterator can become invalid
208         // 2) The package can auto-destruct : we must test its existence 
209         //    after each release
210         // We must also take care of not locking the package pointer 
211         // or any ref count check in Package::ReleaseBlackBoxDescriptor
212         // would be wrong
213
214         // The list of descriptors names at start
215         std::vector<std::string> descnamelist;
216         BlackBoxMapType::iterator i;
217         for (i=pack.lock()->mBlackBoxMap.begin();
218              i!= pack.lock()->mBlackBoxMap.end();
219              ++i)
220           descnamelist.push_back(i->first);
221
222         // Iterator over the initial names
223         std::vector<std::string>::iterator descname;
224         for (descname=descnamelist.begin();
225              descname!=descnamelist.end();
226              ++descname)
227           {
228             // Is package still alive ?
229             if (pack.expired()) 
230               {
231                 bbtkDebugMessage("package",1,"--- Package::Release('"<<
232                                  packname
233                                  <<"') : package expired during release : bailing out"<<bbtkendl);
234                 break;
235               }
236             
237             PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
238             
239           }
240
241         //
242         UnLoadDynamicLibrary(pack);
243         // Unload orphan dl packages 
244         Package::UnLoadReleasedDynamicallyLoadedPackages();
245         
246
247         
248         
249       }
250     
251 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
252
253     bbtkDebugMessage("package",2,"<== Package::Release('"<<
254                      packname<<"')"<<bbtkendl);
255
256     if (!pack.expired())
257       {
258         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
259         long ndesc = pack.lock()->GetBlackBoxMap().size();
260         long nrefs = pack.use_count();
261         
262         bbtkDebugMessage("package",1," ... Package still alive ("
263                          <<nrefs<<" refs / "
264                          <<ndesc<<" descr / dyn="
265                          <<dyn<<")"<<std::endl);
266       }
267     else 
268       {
269         bbtkDebugMessage("package",1," ... Package has been released"
270                          <<std::endl);
271       }
272 #endif
273   }
274   //==========================================================================
275
276   //==========================================================================
277   /// "Releases" the package
278   /// Signals the package that it can free the given descriptor
279   /// if they are no more used and free itself if it is no
280   /// more used
281   /// Note : Any non-weak pointer on the package must have been freed
282   void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
283                                           BlackBoxDescriptor::WeakPointer descr)
284   {
285     std::string packname = pack.lock()->mName;
286     std::string dname = descr.lock()->GetTypeName();    
287     bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
288                      packname<<"','"<<dname<<"') : refs="
289                      <<descr.use_count()<<bbtkendl);
290
291     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
292     long ndesc = pack.lock()->GetBlackBoxMap().size();
293     long nrefs = pack.use_count();
294
295     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
296                      <<ndesc<<" descr / dynamically loaded = "
297                      <<dyn<<std::endl);
298
299     // A package is "free" from any external reference iff :
300     // i) It is not dynamically loaded and nrefs == ndesc 
301     // (each desc references its package) or
302     // ii) It is dynamically loaded and nrefs == ndesc + 1
303     // (A dynamic library holds a static pointer on the package it contains
304     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
305     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
306     if (nrefs == ndesc + dyn) 
307       {
308         PackageReleaseBlackBoxDescriptorInternal(pack,dname);
309       }
310     
311     // If the package is released and dynamically loaded 
312     // then put it in the static list mReleasedDynamicallyLoadedPackages
313     UnLoadDynamicLibrary(pack,false);
314         
315     bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
316                      packname<<"','"<<dname<<"'): refs="
317                      <<descr.use_count()<<bbtkendl);
318     /*
319     if (!pack.expired())
320       {
321         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
322         long ndesc = pack.lock()->GetBlackBoxMap().size();
323         long nrefs = pack.use_count();
324         
325         bbtkDebugMessage("package",3," ... Package still alive ("
326                          <<nrefs<<" refs / "
327                          <<ndesc<<" descr / dyn="
328                          <<dyn<<")"<<std::endl);
329       }
330     else 
331       {
332         bbtkDebugMessage("package",3,"   ... Package has been released"
333                          <<std::endl);
334       }  
335     */
336   }
337   //==========================================================================    
338
339   //==========================================================================
340   /// Opens a dynamic library which contains a bbtk package
341   /// Returns the handler 
342   /// Load the package management symbols from the lib
343   /// returns false if a problem occured hence can be used 
344   /// to test that a dyn lib is a valid bbtk package lib
345   /// NB : The BBTK version exported from the library 
346   ///      is tested against the current bbtk version
347   DynamicLibraryHandler Package::OpenDynamicLibrary
348   ( const std::string& libname,
349     const std::string& package_name,
350     DLGetPackageFunction& getpack,
351     DLDeletePackageFunction& delpack)
352   {
353     bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
354                      <<libname<<")"<<std::endl);
355 #if defined(__GNUC__)
356
357     // Open shared lib
358     void *handler;
359     handler = dlopen(libname.c_str(),
360                      BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
361     if (!handler)
362       {
363         bbtkMessage("package",2,
364                     "Could not open shared library [" <<libname<<"] : "
365                     <<dlerror() << std::endl);
366         return 0;
367       }
368
369     bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
370
371     // Loads the Package bbtk version function 
372     std::string getvername(package_name);
373     getvername += 
374       BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
375     DLGetPackageBBTKVersionFunction getbbtkversion 
376       = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
377     if (!getbbtkversion)
378       {
379         bbtkDebugMessage("package",3,"***"<<std::endl);
380         bbtkMessage("package",2,
381                     "Shared library ["<<libname
382                     <<"] is not a valid bbtk package."
383                     <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
384         dlclose(handler);
385         return 0;
386       }
387
388     bbtkDebugMessage("package",3,"* Symbol ["<<getvername
389                      <<"] found"<<std::endl);
390     // version matches ?
391     if (getbbtkversion() != bbtk::GetVersion())
392       {
393         bbtkMessage("package",2,
394                     "Shared library ["<<libname
395                     <<"] was build with bbtk version "
396                     <<getbbtkversion()
397                     <<" but the current program runs with version "
398                     <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
399         dlclose(handler);
400         return 0;
401         
402       }
403
404     bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
405             // Loads the Package get function
406     std::string getpackname(package_name);
407     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
408     getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
409     if (!getpack)
410       {
411         bbtkMessage("package",2,
412                     "Shared library ["<<libname
413                     <<"] is not a valid bbtk package."
414                     <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
415         dlclose(handler);
416         return 0;
417       }
418   
419     bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
420     // Loads the Package delete function
421                                           
422     std::string delpackname(package_name);
423     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
424     delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
425     if (!delpack)
426       {
427         bbtkMessage("package",2,
428                     "Shared library ["<<libname
429                     <<"] is not a valid bbtk package."
430                     <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
431         dlclose(handler);
432         return 0;
433       }
434     bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);                
435 #elif defined(_WIN32)
436     
437     HINSTANCE handler;
438     
439     SetErrorMode(0);
440     // Open shared lib
441     handler = LoadLibrary(libname.c_str());
442     if (!handler)
443       {
444         bbtkMessage("package",2,
445                     "Could not open shared library [" <<libname<<"]"
446                     << std::endl);
447         DWORD dwErrorCode = 0;
448         dwErrorCode = GetLastError();
449         bbtkMessage("package",2,
450                 "Windows Error: [" << dwErrorCode <<"]"
451                 << std::endl);
452          
453         return 0;
454       }
455     
456     // Loads the Package bbtk version function 
457     std::string getvername(package_name);
458     getvername += 
459       BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
460     DLGetPackageBBTKVersionFunction getbbtkversion 
461       = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
462                                                         getvername.c_str()));
463     if (!getbbtkversion)
464       {
465         FreeLibrary(handler);
466         bbtkMessage("package",2,
467                     "Shared library ["<<libname
468                     <<"] is not a valid bbtk package."
469                     <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
470         return 0;
471       }
472     
473     // version matches ?
474     if (getbbtkversion() != bbtk::GetVersion())
475       {
476         FreeLibrary(handler);
477         bbtkMessage("package",2,
478                     "Shared library ["<<libname
479                     <<"] was build with bbtk version "
480                     <<getbbtkversion()
481                     <<" but the current program runs with version "
482                     <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
483         return 0;
484         
485       }
486
487      // Loads the Package get function
488     std::string getpackname(package_name);
489     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
490     getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
491     if (!getpack)
492       {
493         FreeLibrary(handler);
494         bbtkMessage("package",2,
495                     "Shared library ["<<libname
496                     <<"] is not a valid bbtk package."
497                     <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
498         return 0;
499       }
500     
501     // Loads the Package delete function
502     std::string delpackname(package_name);
503     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
504     delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
505     if (!delpack)
506       {
507         FreeLibrary(handler);
508         bbtkMessage("package",2,
509                     "Shared library ["<<libname
510                     <<"] is not a valid bbtk package."
511                     <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
512         return 0;
513       }
514                                          
515 #else
516     bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
517 #endif
518     
519     return handler;
520   }
521   //==========================================================================
522   
523   //==========================================================================
524   /// Loads a package from a dynamic library
525   Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
526                                                      const std::string& pkgname,
527                                                      const std::string& path)
528   {
529     bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
530                      <<libname<<")"<<std::endl);
531
532     DLGetPackageFunction gf;
533     DLDeletePackageFunction df;
534     DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
535                                                           pkgname,
536                                                           gf,df);
537     if (h==0) return Package::Pointer(); 
538     Package::Pointer p = gf();
539     p->mDynamicLibraryHandler = h;
540     p->mDLDeletePackageFunction = df;
541     
542     std::string separator =
543       ConfigurationFile::GetInstance().Get_file_separator ();
544     //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
545     std::string docreldoc = 
546       separator + "bbdoc" + separator + pkgname + separator + "index.html";
547     std::string reldoc = 
548       ".." + separator + ".." + docreldoc;
549     std::string doc = path + separator + ".." + separator
550       + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
551       + docreldoc;
552     
553     p->SetDocURL(doc);
554     p->SetDocRelativeURL(reldoc);
555     
556     bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
557                      <<libname<<") .. OK"<<std::endl);
558     return p;
559   }
560   //==========================================================================
561
562
563
564
565   //==========================================================================
566   /// UnLoads the package dynamic library (if any)
567   void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
568   {
569     if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
570       return;
571     
572     
573     std::string packname = pack.lock()->GetName();
574     bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
575                      <<packname<<"')"
576                      <<std::endl);
577     
578     if (!pack.lock()->GetBlackBoxMap().empty())
579       {
580         
581         bbtkDebugMessage("package",5,"   Package not empty ... abort"
582                          <<std::endl);
583         return;
584         /*
585         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
586                         <<"BlackBoxMap not empty "
587                         <<BBTK_INTERNAL_ERROR_MESSAGE);
588         */
589         
590       }
591
592     if (pack.use_count()!=1)
593       {
594         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
595                         <<"empty dl package with external refs"
596                         <<BBTK_INTERNAL_ERROR_MESSAGE);
597       } 
598
599     if (doit) 
600       {
601         UnLoad(pack);
602         bbtkDebugMessage("package",5,"==> dynamic library for package '"
603                          <<packname<<"' closed"
604                          <<std::endl);    
605       }
606     else 
607       {
608         mReleasedDynamicallyLoadedPackages.insert(pack);
609         bbtkDebugMessage("package",1,"==> package '"<<packname
610                          <<"' put in the 'to unload' list"
611                          <<std::endl);
612
613       }
614
615     bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
616                      <<packname<<"')"
617                      <<std::endl);
618     
619   }
620   //==========================================================================
621
622   //==========================================================================
623   /// UnLoads released packages that were loaded dynamically
624   /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
625   void Package::UnLoadReleasedDynamicallyLoadedPackages()
626   {
627     bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
628
629     std::set<Package::WeakPointer>::iterator i;
630     for (i=mReleasedDynamicallyLoadedPackages.begin();
631          i!=mReleasedDynamicallyLoadedPackages.end();
632          ++i)
633       {
634         if (!i->expired()) UnLoad(*i);
635       }
636     bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
637   }
638   //==========================================================================
639
640   //==========================================================================
641   void Package::UnLoad(Package::WeakPointer pack)
642   {
643     std::string packname = pack.lock()->GetName();
644     bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
645
646     Package* p = pack.lock().get();
647     
648     DynamicLibraryHandler h = p->mDynamicLibraryHandler;
649     
650     // deletes the package
651     p->mDLDeletePackageFunction();
652     
653     // closes the dl handler
654 #if defined(__GNUC__)  
655     dlclose(h);  
656 #elif defined(_WIN32)
657     FreeLibrary(h);
658 #endif
659
660     bbtkDebugMessage("package",1,"==> dynamic library for package '"
661                      <<packname<<"' closed"
662                      <<std::endl);    
663     bbtkDebugMessage("package",6,"   ... dynamic library unloaded"<<std::endl);
664   }
665   //==========================================================================
666
667   //==========================================================================
668   /// Creates an instance of a black box of type <type> with name <name>
669   BlackBox::Pointer Package::NewBlackBox(const std::string& type, 
670                                          const std::string& name) const
671   {
672     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
673     
674     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
675     if (i == mBlackBoxMap.end())  
676     {
677            bbtkDebugDecTab("Kernel",8);
678            return BlackBox::Pointer();
679     }
680     BlackBox::Pointer bb =i->second->NewBlackBox(name);
681     bbtkDebugDecTab("Kernel",8);
682     return bb;   
683
684   }
685   //==========================================================================
686
687
688
689   //==========================================================================
690   /// Creates an instance of an adaptor of input type <typein> and 
691   /// output type <typeout>  with name <name>
692   BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
693                                 const DataInfo& typeout,
694                                 const std::string& name) const
695   {
696     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
697                         ">::NewAdaptor("
698                         <<typein<<","
699                         <<typeout<<",\""
700                         <<name<<"\")"<<bbtkendl);
701
702     AdaptorKey key(typein,typeout,
703                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
704     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
705     if (i == mAdaptorMap.end())  
706       {
707         bbtkDebugDecTab("Kernel",8);
708         return BlackBox::Pointer();
709       }
710     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
711     bbtkDebugDecTab("Kernel",8);
712     return bb;   
713
714   }
715   //==========================================================================
716
717   //==========================================================================
718   /// Creates an instance of an adaptor of input type <typein> and 
719   /// output type <typeout>  with name <name>
720   BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
721                                       const DataInfo& typeout,
722                                       const std::string& name) const
723   {
724     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
725                         ">::NewWidgetAdaptor("
726                         <<typein<<","
727                         <<typeout<<",\""
728                         <<name<<"\")"<<bbtkendl);
729
730     AdaptorKey key(typein,typeout,
731                    BlackBoxDescriptor::DEFAULT_GUI);
732     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
733     if (i == mAdaptorMap.end())  
734       {
735         bbtkDebugDecTab("Kernel",8);
736         return BlackBox::Pointer();
737       }
738     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
739     bbtkDebugDecTab("Kernel",8);
740     return bb;   
741
742   }
743   //==========================================================================
744
745
746
747   //==========================================================================
748   /// Returns true is the package contains 
749   /// an adaptor of input type <typein> and 
750   /// output type <typeout>
751   /// If successfull then adaptor contains the black box type name
752   bool Package::FindWidgetAdaptor(const DataInfo& typein,
753                                   const DataInfo& typeout,
754                                   std::string& adaptor) const
755   {
756     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
757                         ">::FindWidgetAdaptor("
758                         <<typein<<","
759                         <<typeout<<")"<<bbtkendl);
760    
761     AdaptorKey key(/*typein*/
762                    DataInfo(typeid(void),""),
763                    typeout,
764                    BlackBoxDescriptor::DEFAULT_GUI);
765     // First try to find a single widget adaptor
766     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
767     if (i == mAdaptorMap.end())  
768       {
769         bbtkDebugDecTab("Kernel",8);
770         return false;
771       }
772     adaptor = i->second.lock()->GetTypeName();
773     bbtkDebugDecTab("Kernel",8);
774     return true;   
775
776   }
777   //==========================================================================
778
779
780
781   //==========================================================================
782   /// Returns true is the package contains 
783   /// an adaptor of input type <typein> and 
784   /// output type <typeout>
785   /// If successfull then adaptor contains the black box type name
786   bool Package::FindAdaptor(const DataInfo& typein,
787                             const DataInfo& typeout,
788                             std::string& adaptor) const
789   {
790     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
791                         ">::FindAdaptor("
792                         <<typein<<","
793                         <<typeout<<")"<<bbtkendl);
794     
795     AdaptorKey key(typein,typeout,
796                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
797     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
798     if (i == mAdaptorMap.end())  
799       {
800         bbtkDebugDecTab("Kernel",8);
801         return false;
802       }
803     adaptor = i->second.lock()->GetTypeName();
804     bbtkDebugDecTab("Kernel",8);
805     return true;   
806
807   }
808   //==========================================================================
809
810
811   //==========================================================================
812   /// Registers a black box descriptor in the package
813   bool Package::RegisterBlackBox(BlackBoxDescriptor::Pointer d) 
814   {
815     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
816     
817     BlackBoxMapType::iterator i = mBlackBoxMap.find(d->GetTypeName());
818     if (i!=mBlackBoxMap.end())
819       {
820         bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
821                     <<d->GetTypeName()<<"> which is already in the package");
822         return false;
823       }
824
825     mBlackBoxMap[d->GetTypeName()] = d;
826     //    d->Reference();
827     d->SetPackage(GetThisPointer<Package>());
828     
829     // If it is a default adaptor, also register it in the adaptors map
830     if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
831       {
832         bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
833         
834         TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
835         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
836         DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
837         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
838         AdaptorKey key(infoin,infoout,d->GetKind());
839         
840         AdaptorMapType::const_iterator i;
841         i = mAdaptorMap.find(key);        
842         if (i == mAdaptorMap.end())  
843           {
844             mAdaptorMap[key] = d;
845           }
846         // If already an adaptor registered : error
847         else 
848           {
849             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
850               {
851                 bbtkError("Package <"<<GetName()<<
852                           "> : trying to register black box <"
853                           <<d->GetTypeName()
854                           <<"> as default adaptor but there is already a default adaptor registered (<"
855                           <<i->second.lock()->GetTypeName()<<">)");
856               }
857           }
858       }
859     // If it is a default adaptor, also register it in the adaptors map
860     else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
861       {
862         bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);   
863         
864         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
865         DataInfo infoin(typeid(void),"");
866         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
867         AdaptorKey key(infoin,infoout,d->GetKind());
868
869         AdaptorMapType::const_iterator i;
870         i = mAdaptorMap.find(key);        
871         if (i == mAdaptorMap.end())  
872           {
873             mAdaptorMap[key] = d;
874           }
875         // If already an adaptor registered : error
876         else 
877           {
878             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
879               {
880                 bbtkError("Package <"<<GetName()<<
881                           "> : trying to register black box <"
882                           <<d->GetTypeName()
883                           <<"> as default widget adaptor but there is already a default adaptor registered (<"
884                           <<i->second.lock()->GetTypeName()<<">)");
885               }
886           }
887       }
888     
889
890     bbtkDebugDecTab("Kernel",8);
891    
892     return true;
893   }
894   //==========================================================================
895   
896   //===================================================================
897   void Package::CheckBoxes() const
898   {
899     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
900                 <<" ["<<GetName()<<"]"<<std::endl);
901     BlackBoxMapType::const_iterator i;
902     for (i=mBlackBoxMap.begin();
903          i!=mBlackBoxMap.end();
904          ++i) 
905       {
906         i->second->Check(true);
907       }
908     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
909                 <<" ["<<GetName()<<"] ... OK"<<std::endl);
910   }
911   //===================================================================
912
913
914   //==========================================================================
915   /// Changes the name of a black box type
916   void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
917   { 
918     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
919     // Looking into the bb map
920     BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
921     if (i == mBlackBoxMap.end())  
922       {
923          bbtkDebugDecTab("Kernel",8);
924          bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
925       }
926
927     i->second->SetTypeName(newname);
928     mBlackBoxMap[newname] = i->second;
929     mBlackBoxMap.erase(i);
930
931     bbtkDebugDecTab("Kernel",8);    
932   }
933   //==========================================================================
934
935
936
937   //==========================================================================
938   /// Displays the list of black boxes of the package
939   void Package::PrintBlackBoxes(bool description, bool adaptors) const
940   {
941     unsigned int lmax = 0;
942     std::vector<std::string> names;
943     std::vector<std::string> kinds;
944     std::vector<std::string> descrs;
945
946     BlackBoxMapType::const_iterator i;
947     for (i=mBlackBoxMap.begin();
948          i!=mBlackBoxMap.end();
949          ++i) 
950       {
951         if ( adaptors || 
952              ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) 
953           {
954             std::string name("  ");
955             name += i->second->GetTypeName();
956             names.push_back(name);
957
958             std::string kind;
959             if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
960               {
961                 kind = std::string("[A]");
962               }
963             else if ( i->second->GetKind() == 
964                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
965               {
966                 kind = std::string("[DA]");
967               }
968             kinds.push_back(kind);
969
970             unsigned int l = name.size()+kind.size();
971             if (l>lmax) lmax = l;
972
973             std::string descr;
974             if (description) 
975               {
976                 descr += " : ";
977                 descr += i->second->GetDescription();
978               } 
979             descrs.push_back(descr);
980           }
981       } 
982     
983
984     std::string offs;
985     offs.append(lmax+3,' ');
986     std::vector<std::string>::iterator ni,ci,di;
987     for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
988          ni != names.end(); ++ni, ++ci, ++di)
989       {
990         std::string space;
991         space.append(lmax - ni->size() - ci->size(),' ');
992         bbtkMessage("Help",1,*ni << space << *ci );
993         std::string d(*di);
994         unsigned int dmax = 75 - lmax;
995         //      while (d.size() > dmax ) 
996         //  {
997         if (d.size()>dmax) 
998           bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
999         else 
1000           bbtkMessage("Help",1,d << std::endl);
1001         //    d = d.substr(dmax,d.size());
1002         //  }
1003       }
1004
1005   }
1006   //==========================================================================
1007
1008   //==========================================================================
1009   /// Displays the list of adaptors of the package
1010   void Package::PrintAdaptors(bool description) const
1011   {
1012     BlackBoxMapType::const_iterator i;
1013     for (i=mBlackBoxMap.begin();
1014          i!=mBlackBoxMap.end();
1015          ++i) 
1016       {
1017         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) 
1018           {
1019             bbtkMessage("Help",1,
1020                         "  "<<i->second->GetTypeName());
1021             if ( i->second->GetKind() == 
1022                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
1023               {
1024                 bbtkMessage("Help",1,
1025                             " [default]");
1026               }  
1027             if (description) 
1028               {
1029                 bbtkMessage("Help",1,
1030                             " : "<<i->second->GetDescription());
1031
1032               } 
1033             bbtkMessage("Help",1,std::endl);
1034           }
1035       } 
1036     /*
1037     AdaptorMapType::const_iterator i;
1038     for (i=mAdaptorMap.begin();
1039          i!=mAdaptorMap.end();
1040          ++i) 
1041       {
1042         bbtkMessage("Help",1,
1043                     "  "<<i->second->GetTypeName());
1044         if (detail_level>0) 
1045           {
1046             bbtkMessage("Help",1,
1047                         " : "<<i->second->GetDescription());
1048   
1049           } 
1050         bbtkMessage("Help",1,std::endl);
1051       }
1052     */ 
1053   }
1054   //==========================================================================
1055
1056   //==========================================================================
1057   /// Prints help on a black box
1058   void Package::HelpBlackBox(const std::string& name, bool full) const
1059   {
1060     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1061                         <<name<<"\")"<<bbtkendl);
1062
1063     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1064     if (i == mBlackBoxMap.end())  
1065       {
1066         bbtkDebugDecTab("Kernel",8);
1067         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1068       }
1069     //    bbtkMessage("Help",1,"["<<GetName()<<"] ");
1070     i->second->GetHelp(full);
1071     bbtkDebugDecTab("Kernel",8);
1072
1073   }
1074   //==========================================================================
1075
1076
1077   //==========================================================================
1078   /// Returns true iff the package contains the box of name boxname
1079   bool Package::ContainsBlackBox(const std::string& name) const 
1080   {
1081     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1082                         <<name<<"\")"<<bbtkendl);
1083     
1084     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1085     if (i == mBlackBoxMap.end())  
1086     {
1087       bbtkDebugDecTab("Kernel",8);
1088       return false;
1089     }
1090     bbtkDebugDecTab("Kernel",8);
1091     return true;
1092   }
1093   //==========================================================================
1094
1095
1096  
1097   //==========================================================================
1098   void Package::CreateHtmlPage(const std::string& filename,
1099                                const std::string& caller,
1100                                const std::string& source,
1101                                const std::string& custom_header,
1102                                const std::string& custom_title,
1103                                int detail, 
1104                                int level,
1105                                bool relative_link ) const
1106   {
1107     bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1108                         <<filename<<"\")"<<bbtkendl);
1109
1110     //---------------------
1111     // Open output file
1112     std::ofstream s;
1113     s.open(filename.c_str());
1114     if (!s.good()) 
1115     {
1116        bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1117     }
1118     
1119     //----------------------
1120     // Html head
1121     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
1122
1123     if (custom_title.length() != 0) title = custom_title;
1124
1125     s << "<html lang=\"en\">\n";
1126     s << "<head>\n";
1127     s << "<title>" << title << "</title>\n";
1128     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1129     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1130     s << "<meta name=\"generator\" content=\"\">\n";
1131     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1132     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1133     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1134     s << "pre.display { font-family:inherit }\n";
1135     s << "pre.format  { font-family:inherit }\n";
1136     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1137     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
1138     s << "pre.smallexample { font-size:smaller }\n";
1139     s << "pre.smalllisp    { font-size:smaller }\n";
1140     s << "span.sc    { font-variant:small-caps }\n";
1141     s << "span.roman { font-family:serif; font-weight:normal; } \n";
1142     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
1143     s << "--></style>\n";
1144     s << "</head>\n";
1145     //----------------------
1146
1147     //----------------------
1148     // Html body
1149     s << "<body>\n";
1150     s << "<a name=\"Top\"></a>\n"; 
1151     
1152     //----------------------
1153     // Header
1154     if ( custom_header.length() != 0) 
1155       {
1156         if ( custom_header != "none" )
1157           { 
1158             std::ifstream in;
1159             in.open(custom_header.c_str());    
1160             if (!in.good()) 
1161               {
1162                 bbtkError("Could not open file \""<<custom_header<<"\"");
1163               }
1164             char buffer[512];
1165             while (!in.eof()) 
1166               {
1167                 in.getline(buffer,512);
1168                 std::string line(buffer);
1169                 s << line;
1170               }
1171             in.close();
1172             s << "<hr>\n";
1173            
1174             /*   
1175             s << "<object data=\"" << custom_header 
1176               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1177               << custom_header <<" could not be embedded.</object>\n";
1178             
1179             s << "<hr>\n";
1180             */
1181           }
1182       }
1183
1184     else 
1185       {
1186         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1187         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1188         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1189           << GetDescription() << "</TD></TR>\n";
1190         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1191           << GetAuthor() << "</TD></TR>\n";
1192         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1193           << GetCategory() << "</TD></TR>\n";
1194         s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1195           << GetVersion() << "</TD></TR>\n";
1196         s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1197           << bbtk::GetVersion() << "</TD></TR>\n";
1198         s << "</TABLE>\n";
1199       }
1200
1201     //-------------------
1202     // Table of contents
1203     // Black boxes list
1204     //  s << "<div class=\"contents\">\n";
1205     s << "<p><b> Black Boxes : </b>\n";
1206     s << "<ul>\n";
1207
1208     s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1209
1210     BlackBoxMapType::const_iterator i;
1211     for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) 
1212       {
1213         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD) 
1214           continue;
1215         
1216         std::string name = i->second->GetTypeName();
1217         Utilities::html_format(name);
1218         std::string descr = i->second->GetDescription();
1219         //Utilities::html_format(descr);
1220
1221         s << "<TR>";
1222         s << "<TD style='vertical-align: top;'>";
1223         s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1224           <<"\" href=\"#"<<name<<"\">"
1225           <<name<<"</a>";
1226         s << "</TD> ";
1227         s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1228         s << "</TR>\n";
1229       }    
1230     s << "</TABLE>\n";
1231     
1232     
1233     s << "</ul>\n";
1234     s << "</div>\n";
1235     
1236     //-------------------
1237     // Adaptors list
1238     if (mAdaptorMap.size()>0) 
1239       {
1240         //  s << "<div class=\"contents\">\n";
1241         s << "<p><b> Adaptors : </b>\n";
1242         s << "<ul>\n";
1243
1244         //    BlackBoxMapType::const_iterator i;
1245         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1246         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) 
1247           {
1248             if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) 
1249               continue;
1250     
1251             std::string name = i->second->GetTypeName();
1252             Utilities::html_format(name);
1253             std::string descr = i->second->GetDescription();
1254     
1255             s << "<TR>";
1256             s << "<TD style='vertical-align: top;'>";
1257             s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1258               <<"\" href=\"#"<<name<<"\">"
1259               <<name<<"</a>";
1260             s << "</TD> ";
1261             s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1262             s << "</TR>\n";
1263           }    
1264         s << "</TABLE>\n";
1265
1266         s << "</ul>\n";
1267         s << "</div>\n";
1268       }
1269     
1270     
1271     //  s << "<div class=\"node\">\n";
1272
1273     //    s << "<p><hr>\n";
1274     //    s << "<a name=\"Top\"></a>\n";
1275     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1276     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1277     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
1278     
1279     //    s << "</div>\n";
1280
1281     //----------------------
1282     // Boxes doc
1283
1284     //-------------------
1285     // Computes output directory from filename to pass it to 
1286     // BlackBoxDescriptor::InsertHtmlHelp
1287     std::string dir;
1288
1289     std::string::size_type slash_position = filename.find_last_of("/\\");
1290
1291
1292         if (slash_position != std::string::npos) {
1293       if (slash_position == 0)
1294          slash_position = 1;  
1295       dir = filename.substr(0,slash_position);
1296     }
1297
1298     for (i=mBlackBoxMap.begin();
1299          i!=mBlackBoxMap.end();
1300          ++i) 
1301       {
1302         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1303       }    
1304
1305     //----------------------
1306     // Footer 
1307     time_t rawtime;
1308     tm * ptm;
1309     time ( &rawtime );
1310     ptm = gmtime ( &rawtime );
1311
1312     s << "<p><hr>\n";
1313     s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1314       //      <<source<<"</b>
1315       <<"on "
1316       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
1317       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1318     s << "</body></html>\n"; 
1319     s.close();
1320     //----------------------
1321
1322     // End
1323     bbtkDebugDecTab("Kernel",9);
1324   }
1325   //==========================================================================
1326   
1327   //==========================================================================
1328   std::string  Package::GetObjectName() const 
1329   { 
1330     return std::string("Package '")+mName+std::string("'"); 
1331   }
1332   //==========================================================================
1333
1334   //==========================================================================
1335   std::string Package::GetObjectInfo() const 
1336   {
1337     std::stringstream i;
1338     i << "  - "<<mBlackBoxMap.size() << " boxes" << std::endl;
1339     if (mDynamicLibraryHandler) 
1340       {
1341         i<< "  - Loaded from dynamic library"<<std::endl;
1342       }
1343     return i.str();
1344   }
1345   //==========================================================================
1346
1347
1348   //==========================================================================
1349   size_t  Package::GetObjectSize() const 
1350   {
1351     size_t s = Superclass::GetObjectSize();
1352     s += Package::GetObjectInternalSize();
1353     return s;
1354   }
1355   //==========================================================================
1356   //==========================================================================
1357   size_t  Package::GetObjectInternalSize() const 
1358   {
1359     size_t s = sizeof(Package);
1360     return s;
1361   }
1362   //==========================================================================
1363   //==========================================================================
1364   size_t  Package::GetObjectRecursiveSize() const 
1365   {
1366     size_t s = Superclass::GetObjectRecursiveSize();
1367     s += Package::GetObjectInternalSize();
1368     
1369     BlackBoxMapType::const_iterator i;
1370     for (i = mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i )
1371       {
1372         s += i->second->GetObjectRecursiveSize();
1373       }
1374     return s;
1375   }
1376   //==========================================================================
1377   
1378   //==========================================================================
1379   std::set<Package::WeakPointer> 
1380   Package::mReleasedDynamicallyLoadedPackages;
1381   //==========================================================================
1382 }
1383