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