scanner.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:14k
- /*
- * ===========================================================================
- * PRODUCTION $Log: scanner.cpp,v $
- * PRODUCTION Revision 1000.4 2004/06/01 20:49:09 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.29
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: scanner.cpp,v 1000.4 2004/06/01 20:49:09 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- * Command-line utility to scan a plugin directory and produce a plug-in
- * cache file
- */
- #include <ncbi_pch.hpp>
- #include <corelib/ncbiapp.hpp>
- #include <corelib/ncbiargs.hpp>
- #include <corelib/ncbidll.hpp>
- #include <corelib/ncbienv.hpp>
- #include <corelib/ncbifile.hpp>
- #include <corelib/ncbireg.hpp>
- #include <gui/core/version.hpp>
- #include <gui/core/plugin_factory.hpp>
- #include <gui/plugin/PluginCache.hpp>
- #include <gui/plugin/PluginInfo.hpp>
- #include <serial/serial.hpp>
- #include <serial/objostrasnb.hpp>
- USING_NCBI_SCOPE;
- USING_SCOPE(objects);
- /////////////////////////////////////////////////////////////////////////////
- // CScannerApp::
- class CScannerApp : public CNcbiApplication
- {
- public:
- CScannerApp();
- private:
- int m_Plugins;
- virtual void Init(void);
- virtual int Run(void);
- virtual void Exit(void);
- };
- CScannerApp::CScannerApp()
- : m_Plugins(0)
- {
- }
- /////////////////////////////////////////////////////////////////////////////
- // Init test for all different types of arguments
- void CScannerApp::Init(void)
- {
- // Create command-line argument descriptions class
- auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
- // Specify USAGE context
- arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
- "Plug-in cache maintenance program");
- arg_desc->AddFlag("v", "Version");
- arg_desc->AddFlag("strict", "Strict");
- arg_desc->AddPositional("dir", "Directory to scan",
- CArgDescriptions::eString);
- // Setup arg.descriptions for this application
- SetupArgDescriptions(arg_desc.release());
- }
- /////////////////////////////////////////////////////////////////////////////
- // Run test (printout arguments obtained from command-line)
- int CScannerApp::Run(void)
- {
- // Get arguments
- CArgs args = GetArgs();
- if (args["v"]) {
- cerr << "gbench_plugin_scan, version "
- << CPluginVersion::eMajor << "." << CPluginVersion::eMinor << endl;
- cerr << "build date: " << __DATE__ << " " << __TIME__ << endl;
- return 0;
- }
- string dir_name = args["dir"].AsString();
- string cache_file = dir_name + "/plugin-cache";
- bool strict = args["strict"];
- CNcbiRegistry plugin_cache;
- // okay, now we scan a directory and read it
- // this is operating-system specific!
- int libs_scanned = 0;
- int plugins_registered = 0;
- cout << "scanning plugin directory " << dir_name << "..." << endl;
- CPluginCache cache;
- CDir dir(dir_name);
- if ( !dir.Exists() ) {
- cout << " directory " << dir_name << " does not exist" << endl;
- return 1;
- }
- CDir::TMode mode;
- dir.GetMode(&mode);
- if ( !(mode & CDir::fWrite) ) {
- cout << " cannot update cache in directory " << dir_name
- << ": directory is not writeable" << endl;
- return 1;
- }
- CDir::TEntries entries = dir.GetEntries("*");
- ITERATE (CDir::TEntries, entry_iter, entries) {
- if ( !(*entry_iter)->IsFile() ) {
- continue;
- }
- string full_path = (*entry_iter)->GetPath();
- string path = (*entry_iter)->GetDir();
- string file = (*entry_iter)->GetName();
- // screen for platform-specific libraries
- #ifdef NCBI_OS_MSWIN
- // Winders: must be name.dll
- if (file.find(".dll") != file.length() - 4) {
- continue;
- }
- #elif defined(NCBI_OS_UNIX) || defined(NCBI_OS_LINUX)
- // Unix / MacOS X: must be libname.so
- if (file.find(".so") != file.length() - 3 ||
- file.find("lib") != 0) {
- continue;
- }
- #endif
- // given that we have a library, see if this library corresponds to our
- // criteria for a plug-in
- try {
- LOG_POST(Info << "evaluating " << file << "...");
- // ideally, we should load our plugin and unload it after we're
- // done registering our plugins. practically, on some compilers,
- // this presents some seriously nasty issues regarding
- // initialization of statics - static a living in this app is
- // initialized by this app, then initialized again by the plugin.
- // When the plugin exits, it doesn't get de-initialized, but the
- // reference living in the static is to a piece of invalid memory.
- // This occurs only when genome workbench is linked against static
- // libraries, and does appear to be somewhat platform specific
- #if defined (NCBI_COMPILER_WORKSHOP) || defined(NCBI_OS_OSF1) || defined(NCBI_COMPILER_METROWERKS) || defined(NCBI_OS_DARWIN)
- CDll dll(path, file, CDll::eLoadNow);
- #else
- CDll dll(path, file, CDll::eLoadNow, CDll::eAutoUnload);
- #endif
- CPluginFactoryBase::FPluginEntryPoint get_plugins;
- get_plugins = dll.GetEntryPoint_Func("NCBIGBenchGetPlugins",
- &get_plugins);
- if ( !get_plugins ) {
- LOG_POST(Info
- << "rejecting " << file << ": no plugin entry point");
- continue;
- }
- list<CPluginFactoryBase*> plugins;
- get_plugins(plugins);
- cout << " scanning plugin library " << file << "..." << endl;
- ++libs_scanned;
- ITERATE(list<CPluginFactoryBase*>, plug_iter, plugins) {
- CRef<CPluginInfo> info(new CPluginInfo);
- (*plug_iter)->GetInfo(*info);
- if ( !CPluginVersion::CheckVersion(info->GetVer_major(),
- info->GetVer_minor()) ) {
- LOG_POST(Warning
- << "rejecting plugin library " << file
- << ": version mismatch");
- LOG_POST(Warning
- << " (framework version: "
- << (int)CPluginVersion::eMajor << "."
- << (int)CPluginVersion::eMinor << ", "
- << "plugin version: "
- << info->GetVer_major() << "."
- << info->GetVer_minor() << ")");
- LOG_POST(Warning
- << " (plugin revision: "
- << info->GetVer_revision() << ", "
- << "plugin build date: "
- << info->GetVer_build_date());
- }
- cache.AddPlugin(file, *info);
- cout << " registering plugin "
- << info->GetClass_name() << endl;
- ++plugins_registered;
- }
- }
- catch (CException& e) {
- cout << " error loading " << file << ": " << e.GetMsg() << endl;
- if (strict) {
- throw;
- }
- }
- catch (...) {
- cout << " error loading " << file << endl;
- if (strict) {
- throw;
- }
- }
- }
- cout << " writing plugin cache..." << endl;
- try {
- auto_ptr<CObjectOStream> os(CObjectOStream::Open(eSerial_AsnText,
- cache_file));
- *os << cache;
- }
- catch (CException& e) {
- LOG_POST(Error << "failed to write cache: " << e.GetMsg());
- return 1;
- }
- catch (exception& e) {
- LOG_POST(Error << "failed to write cache: " << e.what());
- return 1;
- }
- catch (...) {
- LOG_POST(Error << "failed to write cache: unknown error");
- return 1;
- }
- cout << " done. " << libs_scanned;
- if (libs_scanned != 1) {
- cout << " libraries scanned, ";
- } else {
- cout << " library scanned, ";
- }
- cout << plugins_registered;
- if (plugins_registered != 1) {
- cout << " plugins registered." << endl;
- } else {
- cout << " plugin registered." << endl;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Cleanup
- void CScannerApp::Exit(void)
- {
- SetDiagStream(0);
- }
- /////////////////////////////////////////////////////////////////////////////
- // MAIN
- int main(int argc, const char* argv[])
- {
- // Execute main application function
- return CScannerApp().AppMain(argc, argv, 0, eDS_Default, 0);
- }
- /*
- * ===========================================================================
- * $Log: scanner.cpp,v $
- * Revision 1000.4 2004/06/01 20:49:09 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.29
- *
- * Revision 1.29 2004/05/21 22:27:42 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.28 2004/05/12 22:01:02 ucko
- * Don't attempt to unload plugins on Darwin.
- *
- * Revision 1.27 2004/03/30 20:09:09 dicuccio
- * Added try/catch around writing of plugin cache to deal with errors more
- * gracefully
- *
- * Revision 1.26 2003/12/09 15:45:51 dicuccio
- * Use CException::GetMsg() instead of what()
- *
- * Revision 1.25 2003/11/24 15:42:03 dicuccio
- * Renamed CVersion to CPluginVersion
- *
- * Revision 1.24 2003/11/19 18:15:27 ucko
- * Adjust for CDll API change.
- *
- * Revision 1.23 2003/11/06 20:09:47 dicuccio
- * Added USING_SCOPE(objects) to implemnentation files
- *
- * Revision 1.22 2003/09/29 15:43:01 dicuccio
- * Deprecated gui/scope.hpp. Merged gui/core/types.hpp into gui/types.hpp
- *
- * Revision 1.21 2003/07/19 00:43:44 dicuccio
- * Added optional flag for strict error processing: strict error processing will
- * not silently ignore unresolved externals from plugins, it will throw and exit
- *
- * Revision 1.20 2003/07/14 11:22:20 shomrat
- * Plugin messageing system related changes
- *
- * Revision 1.19 2003/06/20 14:48:38 dicuccio
- * Changed CPluginFactory --> CPluginFactoryBase
- *
- * Revision 1.18 2003/06/18 13:51:25 rsmith
- * Mac Codewarrior should not do auto unloads either.
- *
- * Revision 1.17 2003/05/19 13:37:28 dicuccio
- * Moved gui/core/plugin/ -> gui/plugin/
- *
- * Revision 1.16 2003/04/07 14:46:14 ucko
- * OSF/1 fares no better with the native compiler, so always delay
- * unloading on that OS.
- *
- * Revision 1.15 2003/03/31 18:45:15 dicuccio
- * Added obtuse platform-specific work-around: When loading dlls explicitly, it
- * is possible that the dll will re-initialize a static variable in the app.
- * Such variables are left in an undefined state when the explicitly loaded dll
- * is explicitly unloaded. So we simply don't explicitly unload the dlls we've
- * loaded.
- *
- * Revision 1.14 2003/03/11 15:18:57 kuznets
- * iterate -> ITERATE
- *
- * Revision 1.13 2003/03/07 17:33:36 dicuccio
- * Don't scan directories that are not writeable
- *
- * Revision 1.12 2003/02/26 20:57:00 dicuccio
- * Added cast for enum -> int (Solaris compilation error)
- *
- * Revision 1.11 2003/02/26 19:24:14 dicuccio
- * Minor output formatting changes
- *
- * Revision 1.10 2003/02/20 19:50:47 dicuccio
- * Created new plugin architecture, based on ASN.1 spec. Moved GBENCH framework
- * over to use new architecture.
- *
- * Revision 1.9 2003/01/13 13:10:11 dicuccio
- * Namespace clean-up. Retired namespace gui -> converted all to namespace
- * ncbi. Moved all FLUID-generated code into namespace ncbi.
- *
- * Revision 1.8 2003/01/08 15:02:54 dicuccio
- * Updated to match changes in type specification system
- *
- * Revision 1.7 2003/01/03 20:39:13 dicuccio
- * Changed '-version' command line parameter to '-v'
- *
- * Revision 1.6 2002/12/23 14:12:30 dicuccio
- * added new command line option to return the version of the binaries
- *
- * Revision 1.5 2002/11/29 16:14:40 dicuccio
- * Minor change - use direct function pointer call insteadl of dereferencing
- *
- * Revision 1.4 2002/11/25 21:02:15 dicuccio
- * Moved typedefs to class-scope instead of function scope.
- * Added templatized plugin processing function - avoids duplicate
- * functionality. Added scanning for data loader plugins. Changed stored
- * library names to reflect local names instead of full path names.
- *
- * Revision 1.3 2002/11/14 16:23:53 dicuccio
- * Fixed registration of single class for multiple types.
- *
- * Revision 1.2 2002/11/07 18:56:14 dicuccio
- * Minor style changes (use typedef FFooFunc instead of typedef TFooFunc)
- *
- * Revision 1.1 2002/11/06 18:29:26 dicuccio
- * Initial revision
- *
- * ===========================================================================
- */