1 /*=========================================================================
4 Module: $RCSfile: bbtkFactory.cxx,v $
7 Date: $Date: 2008/03/10 06:24:12 $
8 Version: $Revision: 1.29 $
11 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
12 l'Image). All rights reserved. See doc/license.txt or
13 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
15 This software is distributed WITHOUT ANY WARRANTY; without even
16 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 PURPOSE. See the above copyright notices for more information.
19 =========================================================================*/
22 *\brief Class bbtk::Factory : can load and unload dynamic libraries containing
23 * black boxes packages and create instances of the black boxes registered
24 * in the packages loaded.
26 #include "bbtkFactory.h"
27 #include "bbtkMessageManager.h"
28 #include "bbtkConnection.h"
29 #include "bbtkConfigurationFile.h"
30 #include "bbtkUtilities.h"
32 #include <sys/stat.h> // for struct stat stFileInfo
35 #include <direct.h> // for getcwd
38 #include <cctype> // std::toupper
43 typedef Package* (*PackageAccessor)();
44 typedef void (*PackageDeleteFunction)();
47 //===================================================================
52 bbtkDebugMessage("Kernel",7,"Factory::Factory()"<<std::endl);
54 //===================================================================
56 //===================================================================
60 bbtkDebugMessageInc("Kernel",7,"Factory::~Factory()"<<std::endl);
62 bbtkDebugDecTab("Kernel",7);
64 //===================================================================
67 //===================================================================
68 void Factory::CloseAllPackages()
70 bbtkDebugMessageInc("Kernel",7,"Factory::CloseAllPackages()"<<std::endl);
71 while (mPackageMap.begin() != mPackageMap.end())
73 PackageMapType::iterator i = mPackageMap.begin();
76 bbtkDebugDecTab("Kernel",7);
78 //===================================================================
80 //===================================================================
83 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
84 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
85 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
86 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
87 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
88 printf("EED kkkkkkkkkkkkkkkkkkkkkkkk Factory::Reset() \n");
89 bbtkDebugMessageInc("Kernel",7,"Factory::Reset()"<<std::endl);
91 bbtkDebugDecTab("Kernel",7);
93 //===================================================================
96 // ===================================================================
97 bool Factory::DoLoadPackage(std::string libname,
102 #if defined(__GNUC__)
105 handler = dlopen(libname.c_str(),
106 BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
109 // The following is *NOT* a debug time message :
110 // It's a user intended message.
111 // Please don't remove it.
112 bbtkError("Could not open shared library [" <<libname<<"] : "
113 <<dlerror() << std::endl);
115 return false; // try next path
118 // The following is *NOT* a debug time message :
119 // It's a user intended message.
120 // Please don't remove it.
121 bbtkMessage("Output",2," -->[" <<libname<<"] found" << std::endl);
123 // Loads the Package accessor
125 std::string getpackname(pkgname);
126 getpackname += "GetPackage";
127 void *getpack = dlsym(handler, getpackname.c_str());
131 bbtkError("Shared library ["<<libname<<"] is not a valid bbtk package."
132 <<" Symbol ["<<getpackname<<"] :"<<dlerror());
135 // Verifies that the Package delete function is present
136 std::string delfname(pkgname);
137 delfname += "DeletePackage";
138 void *delf = dlsym(handler, delfname.c_str());
142 bbtkError("Shared library ["<<libname<<"] is not a valid bbtk package."
143 <<" Symbol ["<<delfname<<"] :"<<dlerror());
146 #elif defined(_WIN32)
151 handler = LoadLibrary(libname.c_str());
154 // The following is *NOT* a debug time message :
155 // It's a user intended message.
156 // Please don't remove it.
157 bbtkError("Error loading library [" <<libname<<"]" << std::endl);
158 return false;// Problem with the found library
161 bbtkMessage("Output",2," --->[" <<libname<<"] found" << std::endl);
163 // Loads the Package accessor
165 std::string getpackname(pkgname);
166 getpackname += "GetPackage";
167 void *getpack = GetProcAddress(handler, getpackname.c_str());
170 FreeLibrary(handler);
171 bbtkError("[1] Could not load package \""<<pkgname
172 <<"\" : "<<getpackname<<" symbol not found (is it a bbtk package lib ?)");
173 // look how to get the error message on win
176 // Verifies that the Package delete function is present
177 std::string delfname(pkgname);
178 delfname += "DeletePackage";
179 void *delf = GetProcAddress(handler, delfname.c_str());
182 FreeLibrary(handler);
183 bbtkError("[2] Could not load package \""<<pkgname
184 <<"\" : "<<delfname<<" symbol not found (is it a bbtk package lib ?)");
185 // look how to get the error message on win
189 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
192 // Stores the package
193 PackageInfoType pack;
194 pack.mDynamicLibraryHandler = handler;
195 // Invokes the accessor to the PackageUnit pointer
196 pack.mPackage = ((PackageAccessor)getpack)();
198 // Test bbtk build version ok
199 if ( pack.mPackage->GetBBTKVersion() != bbtk::GetVersion() )
201 std::string v(pack.mPackage->GetBBTKVersion());
202 UnLoadPackage(pkgname);
203 bbtkError("Cannot load package ["<<libname<<"]. "
204 <<"Package build with bbtk version "
206 << " whereas application build with version "
207 << bbtk::GetVersion());
210 pack.mPackage->AddFactory(this);
211 mPackageMap[pkgname] = pack;
213 std::string separator =
214 ConfigurationFile::GetInstance().Get_file_separator ();
215 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
216 std::string docreldoc =
217 separator + "bbdoc" + separator + pkgname + separator + "index.html";
219 ".." + separator + ".." + docreldoc;
220 std::string doc = path + separator + ".." + separator
221 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
224 pack.mPackage->SetDocURL(doc);
225 pack.mPackage->SetDocRelativeURL(reldoc);
227 //===================================================================
228 bbtkMessage("Output",2,pack.mPackage->GetName()<<" "
229 <<pack.mPackage->GetVersion()
231 <<pack.mPackage->GetBBTKVersion()<<") "
232 <<pack.mPackage->GetAuthor() << " Category(s) :"
233 <<pack.mPackage->GetCategory()
235 bbtkMessage("Output",2,pack.mPackage->GetDescription()<<std::endl);
236 //===================================================================
238 bbtkDebugDecTab("Kernel",7);
242 //===================================================================
243 /// \brief Loads a package.
245 /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
246 /// Tries to open the dynamic library :
247 /// - "libbb<name>.so" for linux systems,
248 /// - "bb<name>.dll" for windows systems.
249 /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
250 /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
251 /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
253 /// now, filename is only the last name (no longer the full name!)
254 /// it will be searched within *all* the paths given in bbtk_config.xml
258 void Factory::LoadPackage( const std::string& name )
260 // Note : in the following :
261 // name : the user supplied name
262 // - abreviated name e.g. pkg pkg.so libbpkg libbbpkg.so
263 // - relative full name e.g. ./libbbpkg.so ../../libbbpkg.so
264 // - absolute full name e.g. /home/usrname/proj/lib/libbbpkg.so
265 // same for Windows, with c:, d: ...
267 // lastname : string before the last / (if any), or user supplied name
269 bbtkDebugMessageInc("Kernel",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
270 bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
272 std::vector<std::string> package_paths;
273 std::string libname; // full path library name
274 std::string pkgname; // e.g. libbb<pkgname>.so
277 pkgname = Utilities::ExtractPackageName(name,upath);
279 bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
280 bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
282 // no loading package if already loaded
283 PackageMapType::iterator iUnload;
284 iUnload = mPackageMap.find(pkgname);
285 if (iUnload != mPackageMap.end())
287 bbtkMessage("Output",2,"["<< pkgname <<"] already loaded" << std::endl);
291 // =================================================
292 // The following structure was checked to work
293 // with any type of relative/absolute path.
294 // Please don't modify it without checking
295 // *all* the cases. JP
296 //==================================================
298 //std::cout << "upath [" << upath << "]" << std::endl;
301 bool foundFile = false;
303 // If path provided by user will be the first scanned :
304 // push it into vector of paths
305 if (upath.length()>0) // ------------------------------------- check user supplied location
307 if (name[0] != '.' && name[0] != '/' && name[1]!= ':')
309 bbtkError("Use absolute or relative path name! ["<<name<<"] is an illegal name");
313 // std::string path = Utilities::ExpandLibName(upath, false);
314 std::string path = Utilities::ExpandLibName(name,false); // keep last item, here.
319 Utilities::ExtractPackageName(path,p2);
320 //libname = Utilities::MakeLibnameFromPath(path, pkgname);
321 libname = Utilities::MakeLibnameFromPath(p2, pkgname); // remove last item
322 // Check if library exists
323 if ( !Utilities::FileExists(libname) )
325 // The following is *NOT* a debug time message :
326 // It's a user intended message.
327 // Please don't remove it.
328 bbtkMessage("Output",3," [" <<libname
329 <<"] : doesn't exist" <<std::endl);
333 ok = DoLoadPackage( libname, pkgname, path);
338 bbtkError("Path ["<<upath<<"] doesn't exist");
342 else // ----------------------------------------------------- iterate on the paths
346 package_paths = ConfigurationFile::GetInstance().Get_package_paths();
347 std::vector<std::string>::iterator i;
348 for (i=package_paths.begin();i!=package_paths.end();++i)
353 // we *really* want '.' to be the current working directory
356 char buf[2048]; // for getcwd
357 char * currentDir = getcwd(buf, 2048);
358 std::string cwd(currentDir);
362 libname = Utilities::MakeLibnameFromPath(path, pkgname);
364 bbtkMessage("Debug",2,"-> Trying to load [" << libname << "]" <<std::endl);
366 // Check if library exists
367 if ( !Utilities::FileExists(libname) )
369 // The following is *NOT* a debug time message :
370 // It's a user intended message.
371 // Please don't remove it.
372 bbtkMessage("Output",3,
373 " [" <<libname <<"] : doesn't exist" <<std::endl);
374 continue; // try next path
378 // Try to Load the library
380 ok = DoLoadPackage( libname, pkgname, path);
383 bbtkMessage("Debug",2," OK"<<std::endl);
384 break; // a package was found; we stop iterating
386 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
390 if( !ok ) // nothing was loaded
394 bbtkError("Could not find package ["<<pkgname<< "]");
398 #if defined(__GNUC__)
399 bbtkError("Could not load package ["<< pkgname
400 <<"] :" << std::endl << " " << dlerror());
401 #elif defined(_WIN32)
402 bbtkError("Could not load package ["<<pkgname
403 <<"] : " << std::endl << " " <<libname<<" not found");
405 // look how to get the error message on win
407 // it is the bordel !! (the bloody fucking bordel, you mean?)
408 // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
412 bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
416 //===================================================================
417 /// \brief UnLoads a package.
419 /// The package must have been previously loaded by LoadPackage.
420 /// If the entry is found in the map, calls ClosePackage
421 void Factory::UnLoadPackage( const std::string& name )
423 bbtkDebugMessageInc("Kernel",7,"Factory::UnLoadPackage(\""
424 <<name<<"\")"<<std::endl);
426 PackageMapType::iterator i;
427 i = mPackageMap.find(name);
428 if (i == mPackageMap.end())
430 bbtkError("cannot unload package \""<<name
431 <<"\" : package not loaded !");
434 bbtkDebugDecTab("Kernel",7);
436 //===================================================================
439 //===================================================================
440 /// \brief Close the package referenced by the iterator
442 /// First removes the factory from the set of factories which use the package
443 /// If the set is empty then :
444 /// If it is a dynamically loaded package :
445 /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
446 /// - Closes the dynamic library
448 /// - deletes the package normally
450 /// Finally erases the package entry in the packages map
451 void Factory::ClosePackage(PackageMapType::iterator& i)
453 bbtkDebugMessageInc("Kernel",7,"Factory::ClosePackage(\""
454 <<i->second.mPackage->GetName()
458 // Removes this from the set of factories which use the package
459 i->second.mPackage->RemoveFactory(this);
461 // If no more factory which use it
462 if (i->second.mPackage->GetFactorySet().empty())
464 // If it is a dynamically loaded package
465 if (i->second.mDynamicLibraryHandler)
469 // Loads the Package delete function
471 std::string delfname(i->second.mPackage->GetName());
472 delfname += "DeletePackage";
473 #if defined(__GNUC__)
474 void *delf = dlsym(i->second.mDynamicLibraryHandler, delfname.c_str());
477 bbtkError("could not close package \""
478 <<i->second.mPackage->GetName()
479 <<"\" :"<<dlerror());
481 #elif defined(_WIN32)
482 void *delf = GetProcAddress(i->second.mDynamicLibraryHandler,
486 bbtkError("could not close package \""
487 <<i->second.mPackage->GetName()
489 <<" symbol not found (how did you open it ???");
490 //<<"\" :"<<dlerror());
494 // deletes the package
495 ((PackageDeleteFunction)delf)();
497 // closes the dl handler
498 #if defined(__GNUC__)
499 dlclose(i->second.mDynamicLibraryHandler);
500 #elif defined(_WIN32)
502 FreeLibrary(i->second.mDynamicLibraryHandler);
508 // If it is a manually inserted package : delete it normally
509 delete i->second.mPackage;
513 // in any cases remove the entry in the map
514 mPackageMap.erase(i);
516 bbtkDebugDecTab("Kernel",7);
518 //===================================================================
522 //===================================================================
523 /// Displays the list of packages loaded
524 void Factory::PrintPackages(bool details, bool adaptors) const
526 bbtkDebugMessageInc("Kernel",9,"Factory::PrintPackages"<<std::endl);
528 PackageMapType::const_iterator i;
529 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
531 bbtkMessage("Help",1, i->first << std::endl);
533 i->second.mPackage->PrintBlackBoxes(false,adaptors);
537 bbtkDebugDecTab("Kernel",9);
539 //===================================================================
541 //===================================================================
542 /// Displays help on a package
543 void Factory::HelpPackage(const std::string& name, bool adaptors) const
545 bbtkDebugMessageInc("Kernel",9,"Factory::HelpPackage(\""<<name<<"\")"
548 PackageMapType::const_iterator i = mPackageMap.find(name);
549 if ( i != mPackageMap.end() )
551 bbtkMessage("Help",1, "Package "<<i->first<<" ");
553 if (i->second.mPackage->GetVersion().length()>0)
554 bbtkMessageCont("Help",1,"v" <<i->second.mPackage->GetVersion());
556 if (i->second.mPackage->GetAuthor().length()>0)
557 bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetAuthor());
559 if (i->second.mPackage->GetCategory().length()>0)
560 bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetCategory());
562 bbtkMessageCont("Help",1,std::endl);
563 bbtkIncTab("Help",1);
564 bbtkMessage("Help",1,i->second.mPackage->GetDescription()<<std::endl);
565 if (i->second.mPackage->GetNumberOfBlackBoxes()>0)
567 bbtkMessage("Help",1, "Black boxes : "<<std::endl);
568 i->second.mPackage->PrintBlackBoxes(true,adaptors);
572 bbtkMessage("Help",1, "No black boxes"<<std::endl);
574 bbtkDecTab("Help",1);
578 bbtkDebugDecTab("Kernel",9);
579 bbtkError("package \""<<name<<"\" unknown");
582 bbtkDebugDecTab("Kernel",9);
584 //===================================================================
586 //===================================================================
587 /// Prints help on the black box of type <name>
588 /// Returns the package to which it belongs
589 void Factory::HelpBlackBox(const std::string& name,
590 std::string& package,
593 bbtkDebugMessageInc("Kernel",9,"Factory::HelpBlackBox(\""<<name<<"\")"
597 PackageMapType::const_iterator i;
598 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
600 if (i->second.mPackage->ContainsBlackBox(name))
602 i->second.mPackage->HelpBlackBox(name,full);
603 package = i->second.mPackage->GetName();
608 bbtkDebugDecTab("Kernel",9);
611 bbtkError("No package of the factory contains any black box <"
615 //===================================================================
618 //===================================================================
619 /// Inserts a package in the factory
620 void Factory::InsertPackage( Package* p )
622 bbtkDebugMessageInc("Kernel",9,"Factory::InsertPackage(\""<<
623 p->GetName()<<"\")"<<std::endl);
626 PackageInfoType pack;
627 pack.mDynamicLibraryHandler = 0;
629 mPackageMap[p->GetName()] = pack;
631 bbtkDebugDecTab("Kernel",9);
633 //===================================================================
635 //===================================================================
636 /// Removes a package from the factory (and deletes it)
637 void Factory::RemovePackage( Package* p )
639 bbtkDebugMessageInc("Kernel",9,"Factory::RemovePackage(\""<<
640 p->GetName()<<"\")"<<std::endl);
642 PackageMapType::iterator i;
643 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
645 if (i->second.mPackage == p) break;
648 if (i!=mPackageMap.end())
654 bbtkError("Factory::RemovePackage(\""<<
655 p->GetName()<<"\") : package absent from factory");
658 bbtkDebugDecTab("Kernel",9);
660 //===================================================================
663 //===================================================================
664 /// Creates an instance of a black box of type <type> with name <name>
665 BlackBox* Factory::NewBlackBox(const std::string& type,
666 const std::string& name) const
668 bbtkDebugMessageInc("Kernel",7,"Factory::NewBlackBox(\""
669 <<type<<"\",\""<<name<<"\")"<<std::endl);
672 PackageMapType::const_iterator i;
673 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
675 b = i->second.mPackage->NewBlackBox(type,name);
680 bbtkError("black box type \""<<type<<"\" unknown");
683 bbtkDebugDecTab("Kernel",7);
686 //===================================================================
688 //===================================================================
689 /// Creates an instance of a black box of type <type> with name <name>
690 BlackBox* Factory::NewAdaptor(TypeInfo typein,
692 const std::string& name) const
694 bbtkDebugMessageInc("Kernel",8,"Factory::NewAdaptor(<"
695 <<TypeName(typein)<<">,<"
696 <<TypeName(typeout)<<">,\""
697 <<name<<"\")"<<bbtkendl);
701 PackageMapType::const_iterator i;
702 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
704 b = i->second.mPackage->NewAdaptor(typein,typeout,name);
710 <<TypeName(typein)<<"> to <"
712 <<"> adaptor available");
715 bbtkDebugDecTab("Kernel",7);
718 //===================================================================
720 //===================================================================
721 /// Creates an instance of a connection
722 Connection* Factory::NewConnection(BlackBox* from,
723 const std::string& output,
725 const std::string& input) const
727 bbtkDebugMessage("Kernel",7,"Factory::NewConnection(\""
728 <<from->bbGetName()<<"\",\""<<output<<"\",\""
729 <<to->bbGetName()<<"\",\""<<input
732 return new Connection(from,output,to,input,this);
734 //===================================================================
738 //===================================================================
739 const Package* Factory::GetPackage(const std::string& name) const
741 bbtkDebugMessageInc("Kernel",9,"Factory::GetPackage(\""<<name<<"\")"
744 PackageMapType::const_iterator i = mPackageMap.find(name);
745 if ( i != mPackageMap.end() )
747 bbtkDebugDecTab("Kernel",9);
748 return i->second.mPackage;
752 bbtkDebugDecTab("Kernel",9);
753 bbtkError("package \""<<name<<"\" unknown");
756 bbtkDebugDecTab("Kernel",9);
758 //===================================================================
760 //===================================================================
761 Package* Factory::GetPackage(const std::string& name)
763 bbtkDebugMessageInc("Kernel",9,"Factory::GetPackage(\""<<name<<"\")"
766 PackageMapType::const_iterator i = mPackageMap.find(name);
767 if ( i != mPackageMap.end() )
769 bbtkDebugDecTab("Kernel",9);
770 return i->second.mPackage;
774 bbtkDebugDecTab("Kernel",9);
775 bbtkError("package \""<<name<<"\" unknown");
778 bbtkDebugDecTab("Kernel",9);
780 //===================================================================
782 //===================================================================
783 void Factory::WriteDotFilePackagesList(FILE *ff)
786 bbtkDebugMessageInc("Kernel",9,"Factory::WriteDotFilePackagesList()"
790 fprintf( ff , "subgraph cluster_FACTORY {\n");
791 fprintf( ff , " label = \"PACKAGES\"%s\n", ";");
792 fprintf( ff , " style=filled%s\n",";");
793 fprintf( ff , " color=lightgrey%s\n",";");
794 fprintf( ff , " rankdir=TB%s\n",";");
797 PackageMapType::const_iterator i;
798 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
800 url=GetPackage(i->first)->GetDocURL();
801 fprintf(ff," %s [shape=ellipse, URL=\"%s\"]%s\n",i->first.c_str(),url.c_str(),";" );
803 fprintf( ff , "}\n\n");
804 bbtkDebugDecTab("Kernel",9);
806 //===================================================================
809 void Factory::ShowGraphTypes(const std::string& name) const
813 PackageMapType::const_iterator i;
814 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
816 if (i->second.mPackage->ContainsBlackBox(name))
818 std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
820 // Don't pollute the file store with "temp_dir" directories ...
821 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
822 std::string directory = "\"" + default_doc_dir + separator + "temp_dir" +separator + "\"";
823 std::string filename2 = default_doc_dir + separator + "temp_dir" + separator + "tmp.html";
826 std::string command("start \"Titre\" /D ");
828 std::string command("gnome-open ");
830 command=command + directory +" tmp.html";
832 ff=fopen(filename2.c_str(),"w");
834 fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
835 fprintf(ff," window.location=\"%s#%s\";\n" , i->second.mPackage->GetDocURL().c_str(),name.c_str() );
836 fprintf(ff,"//--></script></head><body></body></html>\n");
839 //fprintf(ff, "<a href=\"%s#%s\">Link</a>\n", i->second.mPackage->GetDocURL().c_str(),name.c_str() );
841 system( command.c_str() );
846 bbtkDebugDecTab("Kernel",9);
849 bbtkError("No package of the factory contains any black box <"
857 void Factory::CreateHtmlIndex(IndexEntryType type,
858 const std::string& filename)
860 bbtkDebugMessageInc("Kernel",9,"Factory::CreateHtmlIndex(\""
861 <<filename<<"\")"<<bbtkendl);
865 typedef std::map<std::string, std::vector<BlackBoxDescriptor*> > IndexType;
867 // Builds the index map
868 PackageMapType::const_iterator i;
869 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
871 Package* pack = i->second.mPackage;
872 if (pack->GetName()=="user") continue;
873 Package::BlackBoxMapType::const_iterator j;
874 for (j = pack->GetBlackBoxMap().begin();
875 j!= pack->GetBlackBoxMap().end();
880 if ( type==Adaptors )
882 if (j->second->GetKind() == BlackBoxDescriptor::STANDARD )
886 if (j->second->GetKind() != BlackBoxDescriptor::STANDARD )
889 std::vector<std::string> keys;
893 k += pack->GetName();
895 title = "Boxes by package";
897 else if ((type==Initials) || (type==Adaptors))
899 std::string init(" ");
900 init[0] = std::toupper(j->second->GetTypeName()[0]);
901 keys.push_back(init);
902 title = "Alphabetical list";
904 else if (type==Categories)
906 // Split the category string
907 std::string delimiters = ";,";
908 Utilities::SplitString(j->second->GetCategory(),
911 keys.push_back(" NONE");
912 title = "Boxes by category";
916 std::vector<std::string>::const_iterator k;
917 for (k=keys.begin(); k!=keys.end(); ++k )
919 IndexType::iterator p;
921 if (p != index.end())
923 p->second.push_back(j->second);
927 std::vector<BlackBoxDescriptor*> v;
928 v.push_back(j->second);
936 //---------------------
939 s.open(filename.c_str());
942 bbtkError("Factory::CreateHtmlIndex : could not open file '"
946 //----------------------
948 s << "<html lang=\"en\">\n";
950 s << "<title>"<<title<<"</title>\n";
951 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
952 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
953 s << "<meta name=\"generator\" content=\"\">\n";
954 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
955 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
956 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
957 s << "pre.display { font-family:inherit }\n";
958 s << "pre.format { font-family:inherit }\n";
959 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
960 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
961 s << "pre.smallexample { font-size:smaller }\n";
962 s << "pre.smalllisp { font-size:smaller }\n";
963 s << "span.sc { font-variant:small-caps }\n";
964 s << "span.roman { font-family:serif; font-weight:normal; } \n";
965 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
966 s << "--></style>\n";
968 //----------------------
970 //----------------------
973 s << "<a name=\"Top\"></a>\n";
974 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
976 IndexType::iterator ii;
977 for (ii=index.begin();ii!=index.end();++ii)
979 s << "<a href=\"#"<<ii->first<<"\">"<<ii->first<<"</a> ";
982 for (ii=index.begin();ii!=index.end();++ii)
985 s << "<p><a href=\"#Top\">Top</a>";
988 s << "<a name=\""<<ii->first<<"\"></a>\n";
989 s << "<p><a href=\""<<ii->first<<"/index.html\">"
990 << ii->first<<"</a>\n";
992 s << " - \n";
994 s << "<a name=\"doxygen\"></a>\n";
995 s << "<a href=..\\doxygen\\" << ii->first << "/main.html>(Doxygen documentation of the source)</a>\n";
999 s << "<a name=\""<<ii->first<<"\"></a>\n";
1000 s << "<p><b>"<<ii->first<<"</b>\n";
1004 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1006 std::vector<BlackBoxDescriptor*>::iterator di;
1007 for (di=ii->second.begin();di!=ii->second.end();++di)
1009 std::string pack = (*di)->GetPackage()->GetName();
1010 std::string name = (*di)->GetTypeName();
1011 Utilities::html_format(name);
1012 std::string descr = (*di)->GetDescription();
1013 Utilities::html_format(descr);
1015 s << "<TD style='vertical-align: top;'>";
1016 s << " <a href=\""<<pack
1017 <<"/index.html#"<<name<<"\">"
1018 <<pack<<"::"<<name<<"</a>";
1020 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1027 //----------------------
1032 ptm = gmtime ( &rawtime );
1035 s << "Automatically generated by <b>bbi</b> on "
1036 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1037 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1038 s << "</body></html>\n";
1040 //----------------------
1043 bbtkDebugDecTab("Kernel",9);