📄 ncbiapp.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbiapp.cpp,v $ * PRODUCTION Revision 1000.5 2004/06/03 19:28:14 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.85 * PRODUCTION * =========================================================================== *//* $Id: ncbiapp.cpp,v 1000.5 2004/06/03 19:28:14 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: Vsevolod Sandomirskiy, Denis Vakatov * * File Description: * CNcbiApplication -- a generic NCBI application class * CCgiApplication -- a NCBI CGI-application class * */#include <ncbi_pch.hpp>#include <corelib/ncbienv.hpp>#include <corelib/metareg.hpp>#include <corelib/ncbiargs.hpp>#include <corelib/ncbifile.hpp>#include <corelib/ncbiapp.hpp>#if defined(NCBI_OS_MSWIN)# include <corelib/ncbi_os_mswin.hpp># include <corelib/ncbidll.hpp>#endif#if defined(NCBI_OS_UNIX)# include <unistd.h>#endif#if defined(NCBI_OS_DARWIN)# define __NOEXTENSIONS__# include <Carbon/Carbon.h>#endifBEGIN_NCBI_SCOPE/////////////////////////////////////////////////////////////////////////////// Constants//static const char* s_ArgLogFile = "-logfile";static const char* s_ArgCfgFile = "-conffile";static const char* s_ArgVersion = "-version";static void s_DiagToStdlog_Cleanup(void* data){ // SetupDiag(eDS_ToStdlog) CNcbiOfstream* os_log = static_cast<CNcbiOfstream*> (data); delete os_log;}///////////////////////////////////////////////////////// CNcbiApplication//CNcbiApplication* CNcbiApplication::m_Instance;CNcbiApplication* CNcbiApplication::Instance(void){ return m_Instance;}CNcbiApplication::CNcbiApplication(void){ m_DisableArgDesc = false; m_HideArgs = 0; m_StdioFlags = 0; m_CinBuffer = 0; // Register the app. instance if ( m_Instance ) { NCBI_THROW(CAppException, eSecond, "Second instance of CNcbiApplication is prohibited"); } m_Instance = this; // Create empty version info m_Version.reset(new CVersionInfo(0,0)); // Create empty application arguments & name m_Arguments.reset(new CNcbiArguments(0,0)); // Create empty application environment m_Environ.reset(new CNcbiEnvironment); // Create an empty registry m_Config = new CNcbiRegistry; m_OwnsConfig = true;}CNcbiApplication::~CNcbiApplication(void){ m_Instance = 0; FlushDiag(0, true); if (m_CinBuffer) { delete [] m_CinBuffer; } if (m_OwnsConfig) { delete m_Config; }}void CNcbiApplication::Init(void){ return;}void CNcbiApplication::Exit(void){ return;}SIZE_TYPE CNcbiApplication::FlushDiag(CNcbiOstream* os, bool close_diag){ // dyn.cast to CNcbiOstrstream CNcbiOstrstream* ostr = dynamic_cast<CNcbiOstrstream*>(m_DiagStream.get()); if ( !ostr ) { _ASSERT( !m_DiagStream.get() ); return 0; } // dump all content to "os" SIZE_TYPE n_write = 0; if ( os ) n_write = ostr->pcount(); if ( n_write ) { os->write(ostr->str(), n_write); ostr->rdbuf()->freeze(0); } // reset output buffer or destroy if ( close_diag ) { if ( IsDiagStream(m_DiagStream.get()) ) { SetDiagStream(0); } m_DiagStream.reset(0); } else { ostr->rdbuf()->SEEKOFF(0, IOS_BASE::beg, IOS_BASE::out); } // return # of bytes dumped to "os" return (os && os->good()) ? n_write : 0;}#if defined(NCBI_OS_DARWIN)static void s_MacArgMunging(CNcbiApplication& app, int* argcPtr, const char* const** argvPtr, const string& exepath){ // Sometimes on Mac there will be an argument -psn which // will be followed by the Process Serial Number, e.g. -psn_0_13107201 // this is in situations where the application could have no other // arguments like when it is double clicked. // This will mess up argument processing later, so get rid of it. static const char* s_ArgMacPsn = "-psn_"; if (*argcPtr == 2 && NStr::strncmp((*argvPtr)[1], s_ArgMacPsn, strlen(s_ArgMacPsn)) == 0) { --*argcPtr; } if (*argcPtr > 1) return; // Have no arguments from the operating system -- so use the '.args' file // Open the args file. string exedir; CDir::SplitPath(exepath, &exedir); string args_fname = exedir + app.GetProgramDisplayName() + ".args"; CNcbiIfstream in(args_fname.c_str()); if ( !in.good() ) { ERR_POST(Info << "Mac arguments file not found: " << args_fname); return; } vector<string> v; // remember or fake the executable name. if (*argcPtr > 0) { v.push_back((*argvPtr)[0]); // preserve the original argv[0]. } else { v.push_back(exepath); } // grab the rest of the arguments from the file. // arguments are separated by whitespace. Can be on // more than one line. string arg; while (in >> arg) { v.push_back(arg); } // stash them away in the standard argc and argv places. *argcPtr = v.size(); char** argv = new char*[v.size()]; int c = 0; ITERATE(vector<string>, vp, v) { argv[c++] = strdup(vp->c_str()); } *argvPtr = argv;}#endif /* NCBI_OS_DARWIN */int CNcbiApplication::AppMain(int argc, const char* const* argv, const char* const* envp, EAppDiagStream diag, const char* conf, const string& name){ x_SetupStdio(); // Get program executable's name & path. string exepath = FindProgramExecutablePath(argc, argv); // Get program display name string appname = name; if (appname.empty()) { if (!exepath.empty()) { CDirEntry::SplitPath(exepath, NULL, &appname); } else if (argc > 0 && argv[0] != NULL && *argv[0] != '\0') { CDirEntry::SplitPath(argv[0], NULL, &appname); } else { appname = "ncbi"; } } SetProgramDisplayName(appname); // Make sure we have something as our 'real' executable's name. // though if it does not contain a full path it won't be much use. if ( exepath.empty() ) { ERR_POST(Warning << "Warning: Could not determine this application's " "file name and location. Using \"" << appname << "\" instead.\n" "Please fix FindProgramExecutablePath() on this platform."); exepath = appname; } #if defined(NCBI_OS_DARWIN) // We do not know standard way of passing arguments to C++ program on Mac, // so we will read arguments from special file having extension ".args" // and name equal to display name of program (name argument of AppMain). s_MacArgMunging(*this, &argc, &argv, exepath);#endif // Check command line for presence special arguments // "-logfile", "-conffile", "-version" bool is_diag_setup = false; if (!m_DisableArgDesc && argc > 1 && argv) { const char** v = new const char*[argc]; v[0] = argv[0]; int real_arg_index = 1; for (int i = 1; i < argc; i++) { if ( !argv[i] ) { continue; } // Log file if ( NStr::strcmp(argv[i], s_ArgLogFile) == 0 ) { if ( !argv[i++] ) { continue; } const char* log = argv[i]; auto_ptr<CNcbiOfstream> os(new CNcbiOfstream(log)); if ( !os->good() ) { _TRACE("CNcbiApplication() -- cannot open log file: " << log); continue; } _TRACE("CNcbiApplication() -- opened log file: " << log); // (re)direct the global diagnostics to the log.file CNcbiOfstream* os_log = os.release(); SetDiagStream(os_log, true, s_DiagToStdlog_Cleanup, (void*) os_log); diag = eDS_ToStdlog; is_diag_setup = true; // Configuration file } else if ( NStr::strcmp(argv[i], s_ArgCfgFile) == 0 ) { if ( !argv[i++] ) { continue; } conf = argv[i]; // Version } else if ( NStr::strcmp(argv[i], s_ArgVersion) == 0 ) { if ( !argv[i++] ) { continue; } // Print USAGE LOG_POST(appname + ": " + GetVersion().Print()); return 0; // Save real argument } else { v[real_arg_index++] = argv[i]; } } if (real_arg_index == argc ) { delete[] v; } else { argc = real_arg_index; argv = v; } } // Reset command-line args and application name m_Arguments->Reset(argc, argv, exepath); // Reset application environment m_Environ->Reset(envp); // Setup some debugging features from environment variables. if ( !m_Environ->Get(DIAG_TRACE).empty() ) { SetDiagTrace(eDT_Enable, eDT_Enable); } string post_level = m_Environ->Get(DIAG_POST_LEVEL); if ( !post_level.empty() ) { EDiagSev sev; if (CNcbiDiag::StrToSeverityLevel(post_level.c_str(), sev)) { SetDiagFixedPostLevel(sev); } } if ( !m_Environ->Get(ABORT_ON_THROW).empty() ) { SetThrowTraceAbort(true); } // Clear registry content m_Config->Clear(); // Setup for diagnostics try { if ( !is_diag_setup && !SetupDiag(diag) ) { ERR_POST("Application diagnostic stream's setup failed"); } } catch (CException& e) { NCBI_RETHROW(e, CAppException, eSetupDiag, "Application diagnostic stream's setup failed"); } catch (exception& e) { NCBI_THROW(CAppException, eSetupDiag, "Application diagnostic stream's setup failed: " + string(e.what())); } // Load registry from the config file try { if ( conf ) { string x_conf(conf); LoadConfig(*m_Config, &x_conf); } else { LoadConfig(*m_Config, NULL); } } catch (CException& e) { NCBI_RETHROW(e, CAppException, eLoadConfig, "Registry data cannot be loaded"); } catch (exception& e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -