NCBI C++ ToolKit
ncbiapp.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbiapp.cpp 102274 2024-04-15 14:13:11Z ivanov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Vsevolod Sandomirskiy, Denis Vakatov
27  *
28  * File Description:
29  * CNcbiApplication -- a generic NCBI application class
30  * CCgiApplication -- a NCBI CGI-application class
31  *
32  */
33 
34 #include <ncbi_pch.hpp>
35 #ifndef HAVE_LOCAL_NCBI_BUILD_VER_H
36 # define HAVE_LOCAL_NCBI_BUILD_VER_H 1
37 #endif
38 #include <common/ncbi_source_ver.h>
39 #include <corelib/ncbiapp.hpp>
40 #undef CNcbiApplication
41 #undef CComponentVersionInfo
42 #undef CVersion
43 
44 #include <corelib/ncbifile.hpp>
45 #include <corelib/ncbi_system.hpp>
46 #include <corelib/ncbi_param.hpp>
47 #include <corelib/syslog.hpp>
48 #include <corelib/error_codes.hpp>
50 #include <corelib/request_ctx.hpp>
51 #include "ncbisys.hpp"
52 
53 #if defined(NCBI_OS_MSWIN)
54 # include <corelib/ncbi_os_mswin.hpp>
55 # include <corelib/ncbidll.hpp>
56 # include <io.h>
57 # include <fcntl.h>
58 #endif
59 
60 #if defined(NCBI_OS_UNIX)
61 # include <unistd.h>
62 #endif
63 
64 
65 #define NCBI_USE_ERRCODE_X Corelib_App
66 
67 
69 
70 
71 /////////////////////////////////////////////////////////////////////////////
72 // Constants
73 //
74 
75 extern const char* s_ArgLogFile;
76 extern const char* s_ArgCfgFile;
77 extern const char* s_ArgVersion;
78 extern const char* s_ArgFullVersion;
79 extern const char* s_ArgFullVersionXml;
80 extern const char* s_ArgFullVersionJson;
81 extern const char* s_ArgDryRun;
82 extern const char* s_ArgDelimiter;
83 
84 
85 /////////////////////////////////////////////////////////////////////////////
86 // Global variables
87 //
88 
89 static bool s_IsApplicationStarted = false;
90 
91 
92 ///////////////////////////////////////////////////////
93 // CNcbiApplication
94 //
95 
97 {
98  if (m_App) {
99  m_AppLock = make_shared<CReadLockGuard>(m_App->GetInstanceLock());
100  }
101 }
102 
103 
105 {
106 }
107 
108 
109 DEFINE_STATIC_MUTEX(s_InstanceMutex);
110 
112 {
113  return s_InstanceMutex;
114 }
115 
116 
118 
120 {
121  return s_InstanceRWLock.Get();
122 }
123 
124 
126 
128 {
129  return m_Instance;
130 }
131 
132 
134 {
136 }
137 
138 
140  : m_ConfigLoaded(false),
141  m_LogFile(0),
142  m_LogOptions(0)
143 {
145  // Initialize UID and start timer
147  GetDiagContext().InitMessages(size_t(-1));
149 
150  // Verify CPU compatibility
151  // First check. Print critical error only. See second check in x_TryInit() below.
152  {{
153  string err_message;
154  if (!VerifyCpuCompatibility(&err_message)) {
155  ERR_POST_X(22, Critical << err_message);
156  }
157  }}
158 
159  m_DisableArgDesc = 0;
160  m_HideArgs = 0;
161  m_StdioFlags = 0;
162  m_CinBuffer = 0;
164 
165  {
167  // Register the app. instance
168  if (m_Instance) {
170  "Second instance of CNcbiApplication is prohibited");
171  }
172  m_Instance = this;
173  }
174 
175  // Create empty version info
176  m_Version.Reset(new CVersionAPI(build_info));
177 
178  // Set version equal to package one if still empty (might have TeamCity build number)
179  if (m_Version->GetVersionInfo().IsAny()) {
180  auto package_info = m_Version->GetPackageVersion();
181  m_Version->SetVersionInfo(new CVersionInfo(package_info));
182  }
183 
184 #if NCBI_SC_VERSION_PROXY != 0
185  m_Version->AddComponentVersion("NCBI C++ Toolkit",
188 #endif
189  // Create empty application arguments & name
190  m_Arguments.reset(new CNcbiArguments(0,0));
191 
192  // Create empty application environment
193  m_Environ.reset(new CNcbiEnvironment);
194 
195  // Create an empty registry
197 
198  // Phone Home Policy
199  m_PhoneHomePolicy = nullptr;
201 
202  m_DryRun = false;
203 }
204 
205 
207 {
209 }
210 
211 
213 {
214  if (m_PhoneHomePolicy) {
216  }
218  delete m_PhoneHomePolicy;
219  }
220  m_PhoneHomePolicy = policy;
221  if (m_PhoneHomePolicy) {
222  m_PhoneHomePolicy->Apply(this);
223  }
224 };
225 
226 
228 {
229  CThread::sm_IsExiting = true;
230 
231  // Execute exit actions before waiting for all threads to stop.
232  // NOTE: The exit actions may already be executed by higher-level
233  // destructors. This is a final fail-safe place for this.
235 
236 #if defined(NCBI_THREADS)
238 #endif
239 
240  {
242  m_Instance = 0;
243  }
244  FlushDiag(0, true);
245  if (m_CinBuffer) {
246  delete [] m_CinBuffer;
247  }
248 
249 #if defined(NCBI_COMPILER_WORKSHOP)
250  // At least under these conditions:
251  // 1) WorkShop 5.5 on Solaris 10/SPARC, Release64MT, and
252  // 2) when IOS_BASE::sync_with_stdio(false) is called, and
253  // 3) the contents of 'cout' is not flushed
254  // some applications crash on exit() while apparently trying to
255  // flush 'cout' and getting confused by its own guts, with error:
256  // "*** libc thread failure: _thread_setschedparam_main() fails"
257  //
258  // This forced pre-flush trick seems to fix the problem.
259  NcbiCout.flush();
260 #endif
261 }
262 
263 
265 {
266  return dynamic_cast<CNcbiApplication*>(CNcbiApplicationAPI::Instance());
267 }
268 
269 
271  : CNcbiApplicationAPI(build_info)
272 {
273 }
274 
275 
277 {
278  // This earlier execution of the actions allows a safe use of
279  // CNcbiApplication::Instance() from the exit action functions. Instance()
280  // can return NULL pointer if called as part of CNcbiApplicationAPI dtor
281  // when the CNcbiApplication dtor already finished.
283 }
284 
285 
287 {
288  return;
289 }
290 
291 
293 {
294  ERR_POST_X(1, Info << "DryRun: default implementation does nothing");
295  return 0;
296 }
297 
298 
300 {
301  return;
302 }
303 
304 
306 {
307  if ( !m_Args.get() ) {
308  NCBI_THROW(CAppException, eUnsetArgs,
309  "Command-line argument description is not found");
310  }
311  return *m_Args;
312 }
313 
314 
316 {
317  if ( os ) {
318  SetDiagStream(os, true, 0, 0, "STREAM");
319  }
322  return 0;
323 }
324 
325 
326 #if defined(NCBI_OS_DARWIN)
327 static void s_MacArgMunging(CNcbiApplicationAPI& app,
328  int* argcPtr,
329  const char* const** argvPtr,
330  const string& exepath)
331 {
332 
333  // Sometimes on Mac there will be an argument -psn which
334  // will be followed by the Process Serial Number, e.g. -psn_0_13107201
335  // this is in situations where the application could have no other
336  // arguments like when it is double clicked.
337  // This will mess up argument processing later, so get rid of it.
338  static const char* s_ArgMacPsn = "-psn_";
339 
340  if (*argcPtr == 2 &&
341  NStr::strncmp((*argvPtr)[1], s_ArgMacPsn, strlen(s_ArgMacPsn)) == 0) {
342  --*argcPtr;
343  }
344 
345  if (*argcPtr > 1)
346  return;
347 
348  // Have no arguments from the operating system -- so use the '.args' file
349 
350  // Open the args file.
351  string exedir;
352  CDir::SplitPath(exepath, &exedir);
353  string args_fname = exedir + app.GetProgramDisplayName() + ".args";
354  CNcbiIfstream in(args_fname.c_str());
355 
356  if ( !in.good() ) {
357  ERR_POST_X(2, Info << "Mac arguments file not found: " << args_fname);
358  return;
359  }
360 
361  vector<string> v;
362 
363  // remember or fake the executable name.
364  if (*argcPtr > 0) {
365  v.push_back((*argvPtr)[0]); // preserve the original argv[0].
366  } else {
367  v.push_back(exepath);
368  }
369 
370  // grab the rest of the arguments from the file.
371  // arguments are separated by whitespace. Can be on
372  // more than one line.
373  string arg;
374  while (in >> arg) {
375  v.push_back(arg);
376  }
377 
378  // stash them away in the standard argc and argv places.
379  if (v.size() > kMax_Int) {
380  ERR_POST_X(24,
381  Critical << "Overly high argument count " << v.size()
382  << "; truncating to " << kMax_Int);
383  v.resize(kMax_Int);
384  }
385  *argcPtr = static_cast<int>(v.size());
386 
387  char** argv = new char*[v.size()];
388  int c = 0;
389  ITERATE(vector<string>, vp, v) {
390  argv[c++] = strdup(vp->c_str());
391  }
392  *argvPtr = argv;
393 }
394 #endif /* NCBI_OS_DARWIN */
395 
396 
397 NCBI_PARAM_DECL(bool, Debug, Catch_Unhandled_Exceptions);
398 NCBI_PARAM_DEF_EX(bool, Debug, Catch_Unhandled_Exceptions, true,
399  eParam_NoThread, DEBUG_CATCH_UNHANDLED_EXCEPTIONS);
400 typedef NCBI_PARAM_TYPE(Debug, Catch_Unhandled_Exceptions) TParamCatchExceptions;
401 
403 {
404  return TParamCatchExceptions::GetDefault();
405 }
406 
407 
408 NCBI_PARAM_DECL(bool, NCBI, TerminateOnCpuIncompatibility);
409 NCBI_PARAM_DEF_EX(bool, NCBI, TerminateOnCpuIncompatibility, false,
410  eParam_NoThread, NCBI_CONFIG__TERMINATE_ON_CPU_INCOMPATIBILITY);
411 
412 
413 void CNcbiApplicationAPI::x_TryInit(EAppDiagStream diag, const char* conf)
414 {
415  // Load registry from the config file
416  if ( conf ) {
417  string x_conf(conf);
418  LoadConfig(*m_Config, &x_conf);
419  } else {
421  }
422  m_ConfigLoaded = true;
423 
426 
427  // Setup the standard features from the config file.
428  // Don't call till after LoadConfig()
429  // NOTE: this will override environment variables,
430  // except DIAG_POST_LEVEL which is Set*Fixed*.
432 
433  // Application start
434  AppStart();
435 
436  // Verify CPU compatibility
437  // Second check. Print error message and allow to terminate program depends on configuration parameters.
438  // Also, see first check in CNcbiApplicationAPI() constructor.
439  {{
440  string err_message;
441  if (!VerifyCpuCompatibility(&err_message)) {
442  bool fatal = NCBI_PARAM_TYPE(NCBI, TerminateOnCpuIncompatibility)::GetDefault();
443  ERR_POST_X(22, (fatal ? Fatal : Critical) << err_message);
444  }
445  }}
446 
447  // Do init
448 #if (defined(NCBI_COMPILER_ICC) && NCBI_COMPILER_VERSION < 900)
449  // ICC 8.0 have an optimization bug in exceptions handling,
450  // so workaround it here
451  try {
452  Init();
453  }
454  catch (const CArgHelpException&) {
455  throw;
456  }
457 #else
458  Init();
459 #endif
460 
461  // If the app still has no arg description - provide default one
462  if (!m_DisableArgDesc && !m_ArgDesc.get()) {
463  unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
464  arg_desc->SetUsageContext
465  (GetArguments().GetProgramBasename(),
466  "This program has no mandatory arguments");
467  SetupArgDescriptions(arg_desc.release());
468  }
469 }
470 
471 // Macro to define a logging parameter
472 #define NCBI_LOG_PARAM(type,Name,NAME) \
473  NCBI_PARAM_DECL (type, Log, LogApp ## Name); \
474  NCBI_PARAM_DEF_EX(type, Log, LogApp ## Name, false, eParam_NoThread, DIAG_LOG_APP_ ## NAME); \
475  typedef NCBI_PARAM_TYPE(Log, LogApp ## Name) TLogApp ## Name;
476 
477 NCBI_LOG_PARAM(bool, Environment, ENVIRONMENT)
478 NCBI_LOG_PARAM(bool, EnvironmentOnStop, ENVIRONMENT_ON_STOP)
479 NCBI_LOG_PARAM(bool, Registry, REGISTRY)
480 NCBI_LOG_PARAM(bool, RegistryOnStop, REGISTRY_ON_STOP)
481 NCBI_LOG_PARAM(bool, Arguments, ARGUMENTS)
482 NCBI_LOG_PARAM(bool, Path, PATH)
483 NCBI_LOG_PARAM(bool, RunContext, RUN_CONTEXT)
484 NCBI_LOG_PARAM(bool, ResUsageOnStop, RESUSAGE_ON_STOP)
485 
486 
488  eStartEvent = 0x01, ///< right before AppMain()
489  eStopEvent = 0x02, ///< right after AppMain()
490  eOtherEvent = 0x03 ///< any case is fine
491 };
492 
493 
494 /// Flags to switch what to log
496  fLogAppEnvironment = 0x01, ///< log app environment on app start
497  fLogAppEnvironmentStop = 0x02, ///< log app environment on app stop
498  fLogAppRegistry = 0x04, ///< log app registry on app start
499  fLogAppRegistryStop = 0x08, ///< log app registry on app stop
500  fLogAppArguments = 0x10, ///< log app arguments
501  fLogAppPath = 0x20, ///< log app executable path
502  fLogAppResUsageStop = 0x40, ///< log resource usage on app stop
503 };
504 
505 
507 {
508  // Log all
509  if ( TLogAppRunContext::GetDefault() ) {
510  m_LogOptions = 0x7f; // all on
511  return;
512  }
513 
514  // Log registry
515  m_LogOptions |= TLogAppRegistry::GetDefault() ? fLogAppRegistry : 0;
516  m_LogOptions |= TLogAppRegistryOnStop::GetDefault() ? fLogAppRegistryStop : 0;
517 
518  // Log environment
519  m_LogOptions |= TLogAppEnvironment::GetDefault() ? fLogAppEnvironment : 0;
520  m_LogOptions |= TLogAppEnvironmentOnStop::GetDefault() ? fLogAppEnvironmentStop : 0;
521 
522  // Log arguments
523  m_LogOptions |= TLogAppArguments::GetDefault() ? fLogAppArguments : 0;
524 
525  // Log path
526  m_LogOptions |= TLogAppPath::GetDefault() ? fLogAppPath : 0;
527 
528  // Log resources usage
529  m_LogOptions |= TLogAppResUsageOnStop::GetDefault() ? fLogAppResUsageStop : 0;
530 }
531 
532 
533 void s_RoundResUsageSize(Uint8 value_in_bytes, string& suffix, Uint8& value)
534 {
535  const Uint8 limit = 1000;
536 
537  // KB by default
538  suffix = "_KB";
539  value = value_in_bytes / 1024;
540 
541  // Round to MB if value is too big
542  if (value / 1024 > limit) {
543  suffix = "_MB";
544  value /= 1024;
545  }
546 }
547 
548 #define RES_SIZE_USAGE(name, value_in_bytes) \
549  { \
550  string suffix; \
551  Uint8 value; \
552  s_RoundResUsageSize(value_in_bytes, suffix, value); \
553  extra.Print(name + suffix, value); \
554  }
555 
556 #define RES_TIME_USAGE(name, value) \
557  if (value >= 0 ) \
558  extra.Print(name, (Uint8)value)
559 
560 
561 void CNcbiApplicationAPI::x_LogOptions(int /*ELogOptionsEvent*/ event)
562 {
563  const bool start = (event & eStartEvent) != 0;
564  const bool stop = (event & eStopEvent) != 0;
565 
566  // Print environment values
567  if ( (m_LogOptions & fLogAppEnvironment && start) ||
568  (m_LogOptions & fLogAppEnvironmentStop && stop) ) {
570  extra.Print("LogAppEnvironment", "true");
571  list<string> env_keys;
573  env.Enumerate(env_keys);
574  ITERATE(list<string>, it, env_keys) {
575  const string& val = env.Get(*it);
576  extra.Print(*it, val);
577  }
578  }
579 
580  // Print registry values
581  if ( (m_LogOptions & fLogAppRegistry && start) ||
582  (m_LogOptions & fLogAppRegistryStop && stop) ) {
584  extra.Print("LogAppRegistry", "true");
585  list<string> reg_sections;
586  const CNcbiRegistry& reg = GetConfig();
587  reg.EnumerateSections(&reg_sections);
588  ITERATE(list<string>, it, reg_sections) {
589  string section, name;
590  list<string> section_entries;
591  reg.EnumerateEntries(*it, &section_entries);
592  ITERATE(list<string>, it_entry, section_entries) {
593  const string& val = reg.Get(*it, *it_entry);
594  string path = "[" + *it + "]" + *it_entry;
595  extra.Print(path, val);
596  }
597  }
598  }
599 
600  // Print arguments
601  if ( m_LogOptions & fLogAppArguments && start) {
603  extra.Print("LogAppArguments", "true");
604  string args_str;
605  extra.Print("Arguments", GetArgs().Print(args_str));
606  }
607 
608  // Print app path
609  if ( m_LogOptions & fLogAppPath && start) {
611  extra.Print("LogAppPath", "true");
612  extra.Print("Path", GetProgramExecutablePath());
613  }
614 
615  // Print resource usage
616  if ( m_LogOptions & fLogAppResUsageStop && stop) {
618  extra.Print("LogAppResUsage", "true");
619  // Memory usage
620  CProcess::SMemoryUsage mem_usage;
621  if ( CCurrentProcess::GetMemoryUsage(mem_usage) ) {
622  RES_SIZE_USAGE("mem_total", mem_usage.total );
623  RES_SIZE_USAGE("mem_total_peak", mem_usage.total_peak );
624  RES_SIZE_USAGE("rss_mem", mem_usage.resident );
625  RES_SIZE_USAGE("rss_peak_mem", mem_usage.resident_peak);
626  RES_SIZE_USAGE("shared.mem", mem_usage.shared );
627  RES_SIZE_USAGE("data.mem", mem_usage.data );
628  RES_SIZE_USAGE("stack.mem", mem_usage.stack );
629  }
630  // CPU time usage
631  double real, user, sys;
632  if ( CCurrentProcess::GetTimes(&real, &user, &sys, CProcess::eProcess) ) {
633  RES_TIME_USAGE("real.proc.cpu", real);
634  RES_TIME_USAGE("user.proc.cpu", user);
635  RES_TIME_USAGE("sys.proc.cpu", sys);
636  }
637  if ( CCurrentProcess::GetTimes(&real, &user, &sys, CProcess::eChildren) ) {
638  RES_TIME_USAGE("user.child.cpu", user);
639  RES_TIME_USAGE("sys.child.cpu", sys);
640  }
641  if ( CCurrentProcess::GetTimes(&real, &user, &sys, CProcess::eThread) ) {
642  RES_TIME_USAGE("user.thread.cpu", user);
643  RES_TIME_USAGE("sys.thread.cpu", sys);
644  }
645  }
646 }
647 
648 
650  const char* conf,
651  int* exit_code,
652  bool* got_exception)
653 {
654  // Initialize the application
655  try {
656  if ( s_HandleExceptions() ) {
657  try {
658  x_TryInit(diag, conf);
659  }
660  catch (const CArgHelpException&) {
661  // This exceptions will be caught later regardless of the
662  // handle-exceptions flag.
663  throw;
664  }
665  catch (const CArgException&) {
666 // NCBI_RETHROW_SAME(e, "Application's initialization failed");
667  throw;
668  }
669  catch (const CException& e) {
671  "Application's initialization failed", e);
672  *got_exception = true;
673  *exit_code = 2;
674  }
675  catch (const exception& e) {
676  ERR_POST_X(6, "Application's initialization failed: " << e.what());
677  *got_exception = true;
678  *exit_code = 2;
679  }
680  }
681  else {
682  x_TryInit(diag, conf);
683  }
684  }
685  catch (const CArgHelpException& e) {
687  // Print USAGE
689  m_ArgDesc->PrintUsageXml(cout);
690  } else {
692  string str;
693  m_ArgDesc->ShowAllArguments(code == CArgHelpException::eHelpShowAll)->PrintUsage
695  cout << str;
696  }
697  *exit_code = e.GetErrCode() == CArgHelpException::eHelpErr ? 2 : 0;
698  }
701  // Run application
702  if (*exit_code == 1) {
704  if ( s_HandleExceptions() ) {
705  try {
706  *exit_code = m_DryRun ? DryRun() : Run();
707  }
708  catch (CArgException& e) {
709  NCBI_RETHROW_SAME(e, "Application's execution failed");
710  }
711  catch (const CException& e) {
712  CRef<CRequestContext> cur_ctx(&GetDiagContext().GetRequestContext());
713  if (cur_ctx != &e.GetRequestContext()) {
716  "CException thrown", e);
718  }
720  "Application's execution failed", e);
721  *got_exception = true;
722  *exit_code = 3;
723  }
724  catch (const exception& e) {
725  ERR_POST_X(7, "Application's execution failed: " << e.what());
726  *got_exception = true;
727  *exit_code = 3;
728  }
729  }
730  else {
731  *exit_code = m_DryRun ? DryRun() : Run();
732  }
733  }
736 
737  // Close application
738  if ( s_HandleExceptions() ) {
739  try {
740  Exit();
741  }
742  catch (CArgException& e) {
743  NCBI_RETHROW_SAME(e, "Application's cleanup failed");
744  }
745  catch (const CException& e) {
746  NCBI_REPORT_EXCEPTION_X(17, "Application's cleanup failed", e);
747  *got_exception = true;
748  }
749  catch (const exception& e) {
750  ERR_POST_X(8, "Application's cleanup failed: "<< e.what());
751  *got_exception = true;
752  }
753  }
754  else {
755  Exit();
756  }
757 }
758 
759 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
760 static
761 void s_Create_ArgsOrEnvW(
762  vector<string>& storage,
763  AutoArray<const char*>& pointers,
764  const TXChar* const* begin)
765 {
766  const TXChar* const* arg = begin;
767  size_t count = 0;
768  while( *(arg++) )
769  ++count;
770 
771  const char** args = new const char*[count+1];
772  if ( !args ) {
773  NCBI_THROW(CCoreException, eNullPtr, kEmptyStr);
774  }
775  pointers = args;
776 
777  arg = begin;
778  size_t i=0;
779  for (i=0; i<count; ++i) {
780  storage.push_back( _T_STDSTRING( *(arg++) ) );
781  }
782 
783  for (i=0; i < storage.size(); ++i) {
784  args[i] = storage[i].c_str();
785  }
786  args[i] = NULL;
787 }
788 
790 (int argc,
791  const TXChar* const* argv,
792  const TXChar* const* envp,
793  EAppDiagStream diag,
794  const TXChar* conf,
795  const TXString& name)
796 {
797  vector< string> argv_storage;
798  AutoArray<const char*> argv_pointers;
799  if (argv) {
800  s_Create_ArgsOrEnvW(argv_storage, argv_pointers, argv);
801  }
802 
803  vector< string> envp_storage;
804  AutoArray<const char*> envp_pointers;
805  if (envp) {
806  s_Create_ArgsOrEnvW(envp_storage, envp_pointers, envp);
807  }
808 
809  return AppMain(argc,
810  argv == NULL ? NULL : argv_pointers.get(),
811  envp == NULL ? NULL : envp_pointers.get(),
812  diag,
813  conf == NULL ? NULL : (conf == NcbiEmptyXCStr ? NcbiEmptyCStr : _T_CSTRING(conf)),
814  name == NcbiEmptyXString ? NcbiEmptyString : _T_STDSTRING(name));
815 }
816 #endif
817 
819 (int argc,
820  const char* const* argv,
821  const char* const* envp,
822  EAppDiagStream diag,
823  const char* conf,
824  const string& name)
825 {
826  if (conf) {
827  m_DefaultConfig = conf;
828  }
829  x_SetupStdio();
830 
831  // Check if logfile is set in the args.
832  m_LogFile = 0;
833  if (!m_DisableArgDesc && argc > 1 && argv && diag != eDS_User) {
834  for (int i = 1; i < argc; i++) {
835  if ( !argv[i] ) {
836  continue;
837  }
838  if ( NStr::strcmp(argv[i], s_ArgDelimiter) == 0 ) {
839  break;
840  }
841  if ( NStr::strcmp(argv[i], s_ArgLogFile) == 0 ) {
842  if (!argv[++i]) {
843  continue;
844  }
845  m_LogFile = argv[i];
846  } else if (NStr::StartsWith(argv[i], s_ArgLogFile)) {
847  const char *a = argv[i] + strlen(s_ArgLogFile);
848  if (*a == '=') {
849  m_LogFile = ++a;
850  }
851  }
852  }
853  }
854 
855  // Setup logging as soon as possible.
856  // Setup for diagnostics
857  try {
859  } catch (const CException& e) {
860  NCBI_RETHROW(e, CAppException, eSetupDiag,
861  "Application diagnostic stream's setup failed");
862  } catch (const exception& e) {
863  NCBI_THROW(CAppException, eSetupDiag,
864  "Application diagnostic stream's setup failed: " +
865  string(e.what()));
866  }
867 
868  // Get program executable's name & path.
869  string exepath = FindProgramExecutablePath(argc, argv, &m_RealExePath);
870  m_ExePath = exepath;
871 
872  // Get program display name
873  string appname = name;
874  if (appname.empty()) {
875  if (!exepath.empty()) {
876  CDirEntry::SplitPath(exepath, NULL, &appname);
877  } else if (argc > 0 && argv && argv[0] != NULL && *argv[0] != '\0') {
878  CDirEntry::SplitPath(argv[0], NULL, &appname);
879  } else {
880  appname = "ncbi";
881  }
882  }
883  if ( m_ProgramDisplayName.empty() ) {
884  SetProgramDisplayName(appname);
885  }
886 
887  // Make sure we have something as our 'real' executable's name.
888  // though if it does not contain a full path it won't be much use.
889  if ( exepath.empty() ) {
891  << "Warning: Could not determine this application's "
892  "file name and location. Using \""
893  << appname << "\" instead.\n"
894  "Please fix FindProgramExecutablePath() on this platform.");
895  exepath = appname;
896  }
897 
898 #if defined(NCBI_OS_DARWIN)
899  // We do not know standard way of passing arguments to C++ program on Mac,
900  // so we will read arguments from special file having extension ".args"
901  // and name equal to display name of program (name argument of AppMain).
902  s_MacArgMunging(*this, &argc, &argv, exepath);
903 #endif
904 
905  CDiagContext& diag_context = GetDiagContext();
906 
907  // Preparse command line
908  if (PreparseArgs(argc, argv) == ePreparse_Exit) {
909  diag_context.DiscardMessages();
910  return 0;
911  }
912 
913  // Check command line for presence special arguments
914  // "-logfile", "-conffile", "-version"
915  const char* conf_arg = nullptr;
916  if (!m_DisableArgDesc && argc > 1 && argv) {
917  const char** v = new const char*[argc];
918  v[0] = argv[0];
919  int real_arg_index = 1;
920  bool skip = false;
921  for (int i = 1; i < argc; i++) {
922  if ( !argv[i] ) {
923  continue;
924  }
925  if ( NStr::strcmp(argv[i], s_ArgDelimiter) == 0 ) {
926  skip = true;
927  }
928  if (skip) {
929  v[real_arg_index++] = argv[i];
930  continue;
931  }
932  // Log file - ignore if diag is eDS_User - the user wants to
933  // take care about logging.
934  if ( diag != eDS_User &&
935  NStr::strcmp(argv[i], s_ArgLogFile) == 0 ) {
936  if (!argv[++i]) {
937  continue;
938  }
939  v[real_arg_index++] = argv[i - 1];
940  v[real_arg_index++] = argv[i];
941  // Configuration file
942  } else if ( NStr::strcmp(argv[i], s_ArgCfgFile) == 0 ) {
943  if (!argv[++i]) {
944  continue;
945  }
946  v[real_arg_index++] = argv[i - 1];
947  v[real_arg_index++] = argv[i];
948  conf_arg = argv[i];
949 
950  }
951  else if (NStr::StartsWith(argv[i], s_ArgCfgFile)) {
952  v[real_arg_index++] = argv[i];
953  const char* a = argv[i] + strlen(s_ArgCfgFile);
954  if (*a == '=') {
955  conf_arg = ++a;
956  }
957 
958  // Version
959  } else if ( NStr::strcmp(argv[i], s_ArgVersion) == 0 ) {
960  delete[] v;
961  // Print VERSION
963  diag_context.DiscardMessages();
964  return 0;
965 
966  // Full version
967  } else if ( NStr::strcmp(argv[i], s_ArgFullVersion) == 0 ) {
968  delete[] v;
969  // Print full VERSION
970  cout << GetFullVersion().Print( appname );
971  diag_context.DiscardMessages();
972  return 0;
973  } else if ( NStr::strcmp(argv[i], s_ArgFullVersionXml) == 0 ) {
974  delete[] v;
975  // Print full VERSION in XML format
976  cout << GetFullVersion().PrintXml( appname );
977  diag_context.DiscardMessages();
978  return 0;
979  } else if ( NStr::strcmp(argv[i], s_ArgFullVersionJson) == 0 ) {
980  delete[] v;
981  // Print full VERSION in JSON format
982  cout << GetFullVersion().PrintJson( appname );
983  diag_context.DiscardMessages();
984  return 0;
985 
986  // Dry run
987  } else if ( NStr::strcmp(argv[i], s_ArgDryRun) == 0 ) {
988  m_DryRun = true;
989 
990  // Save real argument
991  } else {
992  v[real_arg_index++] = argv[i];
993  }
994  }
995  if (real_arg_index == argc ) {
996  delete[] v;
997  } else {
998  argc = real_arg_index;
999  argv = v;
1000  }
1001  if (conf_arg) {
1002  if (CFile(conf_arg).Exists()) {
1003  conf = conf_arg;
1004  }
1005  else {
1006  ERR_POST_X(23, Critical << "Registry file \"" << conf_arg << "\" not found, aborting.");
1007  Abort();
1008  }
1009  }
1010  }
1011 
1012  // Reset command-line args and application name
1013  m_Arguments->Reset(argc, argv, exepath, m_RealExePath);
1014 
1015  // Reset application environment
1016  m_Environ->Reset(envp);
1017 
1018  // Setup some debugging features from environment variables.
1019  if ( !m_Environ->Get(DIAG_TRACE).empty() ) {
1021  }
1022  string post_level = m_Environ->Get(DIAG_POST_LEVEL);
1023  if ( !post_level.empty() ) {
1024  EDiagSev sev;
1025  if (CNcbiDiag::StrToSeverityLevel(post_level.c_str(), sev)) {
1026  SetDiagFixedPostLevel(sev);
1027  }
1028  }
1029  if ( !m_Environ->Get(ABORT_ON_THROW).empty() ) {
1030  SetThrowTraceAbort(true);
1031  }
1032 
1033  // Clear registry content
1034  m_Config->Clear();
1035 
1036  // Call: Init() + Run() + Exit()
1037  int exit_code = 1;
1038  bool got_exception = false;
1039  s_IsApplicationStarted = true;
1040 
1041  try {
1042  if ( s_HandleExceptions() ) {
1043  try {
1044  x_TryMain(diag, conf, &exit_code, &got_exception);
1045  }
1046  catch (const CArgException&) {
1047  // This exceptions will be caught later regardless of the
1048  // handle-exceptions flag.
1049  throw;
1050  }
1051 #if defined(NCBI_COMPILER_MSVC) && defined(_DEBUG)
1052  // Microsoft promotes many common application errors to exceptions.
1053  // This includes occurrences such as dereference of a NULL pointer and
1054  // walking off of a dangling pointer. The catch-all is lifted only in
1055  // debug mode to permit easy inspection of such error conditions, while
1056  // maintaining safety of production, release-mode applications.
1057  catch (...) {
1058  ERR_POST_X(10, Warning <<
1059  "Application has thrown an exception of unknown type");
1060  throw;
1061  }
1062 #endif
1063  }
1064  else {
1065 #ifdef NCBI_OS_MSWIN
1066  if ( !IsDebuggerPresent() ) {
1068  }
1069 #endif
1070  x_TryMain(diag, conf, &exit_code, &got_exception);
1071  }
1072  }
1073  catch (const CArgException& e) {
1074  // Print USAGE and the exception error message
1075  if ( e.GetErrCode() != CArgException::eNoValue && m_ArgDesc.get() ) {
1076  x_AddDefaultArgs();
1077  string str;
1078  if ( !m_ArgDesc->IsSetMiscFlag(CArgDescriptions::fNoUsage) ) {
1079  m_ArgDesc->PrintUsage(str);
1080  cerr << str;
1081  }
1082  if ( !m_ArgDesc->IsSetMiscFlag(CArgDescriptions::fDupErrToCerr) ) {
1083  CStreamDiagHandler* errh =
1084  dynamic_cast<CStreamDiagHandler*>(GetDiagHandler());
1085  if (!errh || errh->GetStream() != &cerr) {
1086  cerr << "Error in command-line arguments. "
1087  "See error logs for more details." << endl;
1088  }
1089  }
1090  else {
1091  cerr << "Error in command-line arguments." << endl;
1092  cerr << e.what() << endl;
1093  }
1094  cerr << string(72, '=') << endl << endl;
1095  }
1097  NCBI_REPORT_EXCEPTION_X(18, "", e);
1098  got_exception = true;
1099  exit_code = 1;
1100  }
1101 
1102  if (!diag_context.IsSetExitCode()) {
1103  diag_context.SetExitCode(exit_code);
1104  }
1105 
1106  if (m_ExitCodeCond == eAllExits
1107  || (got_exception && m_ExitCodeCond == eExceptionalExits)) {
1108  _TRACE("Overriding exit code from " << exit_code
1109  << " to " << m_ExitCode);
1110  exit_code = m_ExitCode;
1111  }
1112 
1113  // Application stop
1114  AppStop(exit_code);
1115 
1116  if ((m_AppFlags & fSkipSafeStaticDestroy) == 0) {
1117  // Destroy short-lived statics
1119  }
1120 
1121  // Exit
1122  return exit_code;
1123 }
1124 
1125 
1126 void CNcbiApplicationAPI::SetEnvironment(const string& name, const string& value)
1127 {
1128  SetEnvironment().Set(name, value);
1129 }
1130 
1131 #if 0
1133 {
1135 }
1136 
1137 void CNcbiApplicationAPI::SetVersion(int major, int minor)
1138 {
1140 }
1141 
1142 void CNcbiApplicationAPI::SetVersion(int major, int minor, int patch)
1143 {
1144  m_Version->SetVersionInfo(major, minor, patch,
1146 }
1147 #else
1149 {
1151 }
1152 #endif
1153 
1154 
1156 {
1157  if ( s_IsApplicationStarted ) {
1158  ERR_POST_X(19, "SetVersion() should be used from constructor of " \
1159  "CNcbiApplication derived class, see description");
1160  }
1162 }
1163 
1165  const SBuildInfo& build_info)
1166 {
1167  if ( s_IsApplicationStarted ) {
1168  ERR_POST_X(19, "SetVersion() should be used from constructor of " \
1169  "CNcbiApplication derived class, see description");
1170  }
1171  m_Version->SetVersionInfo(new CVersionInfo(version), build_info);
1172 }
1173 
1175 {
1176  if ( s_IsApplicationStarted ) {
1177  ERR_POST_X(19, "SetFullVersion() should be used from constructor of "\
1178  "CNcbiApplication derived class, see description");
1179  }
1180  m_Version.Reset( version );
1181 }
1182 
1183 
1185 {
1186  return m_Version->GetVersionInfo();
1187 }
1188 
1190 {
1191  return *m_Version;
1192 }
1193 
1194 
1196 {
1197  m_ArgDesc.reset(arg_desc);
1198 
1199  if ( arg_desc ) {
1200  if ( !m_DisableArgDesc ) {
1201  for(CArgDescriptions* desc : m_ArgDesc->GetAllDescriptions()) {
1202  desc->AddDefaultFileArguments(m_DefaultConfig);
1203  }
1204  }
1205  m_Args.reset(arg_desc->CreateArgs(GetArguments()));
1206  } else {
1207  m_Args.reset();
1208  }
1209 }
1210 
1211 
1213 {
1215  return true;
1216 }
1217 
1218 
1220 {
1222  return true;
1223 }
1224 
1225 
1227  const string* conf,
1228  CNcbiRegistry::TFlags reg_flags)
1229 {
1230  string basename (m_Arguments->GetProgramBasename(eIgnoreLinks));
1231  string basename2(m_Arguments->GetProgramBasename(eFollowLinks));
1232  CMetaRegistry::SEntry entry;
1233 
1234  if ( !conf ) {
1235  if (reg.IncludeNcbircIfAllowed(reg_flags)) {
1237  ("ncbi", CMetaRegistry::eName_RcOrIni);
1238  }
1239  m_ConfigLoaded = true;
1240  return false;
1241  } else if (conf->empty()) {
1243  reg_flags, &reg);
1244  if ( !entry.registry && basename2 != basename ) {
1245  entry = CMetaRegistry::Load(basename2, CMetaRegistry::eName_Ini, 0,
1246  reg_flags, &reg);
1247  }
1249  } else {
1251  reg_flags, &reg);
1252  }
1253  if ( !entry.registry ) {
1254  // failed; complain as appropriate
1255  string dir;
1256  CDirEntry::SplitPath(*conf, &dir, 0, 0);
1257  if (dir.empty()) {
1258  ERR_POST_X(11, Info <<
1259  "Registry file of application \"" << basename
1260  << "\" is not found");
1261  } else {
1262  NCBI_THROW(CAppException, eNoRegistry,
1263  "Registry file \"" + *conf + "\" cannot be opened");
1264  }
1265  // still consider pulling in defaults from .ncbirc
1266  if (reg.IncludeNcbircIfAllowed(reg_flags)) {
1268  ("ncbi", CMetaRegistry::eName_RcOrIni);
1269  }
1270  m_ConfigLoaded = true;
1271  return false;
1272  } else if (entry.registry != static_cast<IRWRegistry*>(&reg)) {
1273  // should be impossible with new CMetaRegistry interface...
1274  if (&reg == m_Config && reg.Empty()) {
1275  m_Config.Reset(dynamic_cast<CNcbiRegistry*>
1276  (entry.registry.GetPointer()));
1277  } else {
1278  // copy into reg
1280  entry.registry->Write(str);
1281  str.seekg(0);
1282  reg.Read(str);
1283  }
1284  }
1285  m_ConfigPath = entry.actual_name;
1286  m_ConfigLoaded = true;
1287  return true;
1288 }
1289 
1290 
1292  const string* conf)
1293 {
1294  return LoadConfig(reg, conf, IRegistry::fWithNcbirc);
1295 }
1296 
1297 
1300  const char* const* /*argv*/)
1301 {
1302  return ePreparse_Continue;
1303 }
1304 
1305 
1307 {
1308  m_DisableArgDesc = disable;
1309 }
1310 
1311 
1313 {
1314  m_HideArgs = hide_mask;
1315 }
1316 
1317 
1319 {
1320  // do not call this function more than once
1321  // and from places other than App constructor
1322  _ASSERT(m_StdioFlags == 0);
1323  m_StdioFlags = stdio_flags;
1324 }
1325 
1326 
1328 {
1329  if ((m_StdioFlags & fNoSyncWithStdio) != 0) {
1330  IOS_BASE::sync_with_stdio(false);
1331  }
1332 
1334 #ifdef NCBI_OS_UNIX
1335  && !isatty(0)
1336 #endif
1337  ) {
1338 #if defined(NCBI_COMPILER_GCC) && defined(NCBI_OS_SOLARIS)
1339  _ASSERT(!m_CinBuffer);
1340  // Ugly workaround for ugly interaction between g++ and Solaris C RTL
1341  const size_t kCinBufSize = 5120;
1342  m_CinBuffer = new char[kCinBufSize];
1343  cin.rdbuf()->pubsetbuf(m_CinBuffer, kCinBufSize);
1344 #endif
1345  }
1346 #ifdef NCBI_OS_MSWIN
1347  if ((m_StdioFlags & fBinaryCin) != 0) {
1348  NcbiSys_setmode(NcbiSys_fileno(stdin), O_BINARY);
1349  }
1350  if ((m_StdioFlags & fBinaryCout) != 0) {
1351  NcbiSys_setmode(NcbiSys_fileno(stdout), O_BINARY);
1352  }
1353 #endif
1354 }
1355 
1357 {
1359  for(CArgDescriptions* desc : m_ArgDesc->GetAllDescriptions())
1360  {
1361  desc->AddStdArguments(mask);
1363  }
1364 }
1365 
1367 {
1368  if (app_name.empty()) return;
1369  m_ProgramDisplayName = app_name;
1370  // Also set app_name in the diag context
1371  if ( GetDiagContext().GetAppName().empty() ) {
1372  GetDiagContext().SetAppName(app_name);
1373  }
1374 }
1375 
1376 
1377 string CNcbiApplicationAPI::GetAppName(EAppNameType name_type, int argc, const char* const* argv)
1378 {
1379  CNcbiApplicationGuard instance = InstanceGuard();
1380  string app_name;
1381 
1382  switch (name_type) {
1383  case eBaseName:
1384  if (instance) {
1385  app_name = instance->GetProgramDisplayName();
1386  } else {
1387  string exe_path = FindProgramExecutablePath(argc, argv);
1388  CDirEntry::SplitPath(exe_path, NULL, &app_name);
1389  }
1390  break;
1391 
1392  case eFullName:
1393  if (instance) {
1394  app_name = instance->GetProgramExecutablePath(eIgnoreLinks);
1395  } else {
1396  app_name = FindProgramExecutablePath(argc, argv);
1397  }
1398  break;
1399 
1400  case eRealName:
1401  if (instance) {
1402  app_name = instance->GetProgramExecutablePath(eFollowLinks);
1403  } else {
1404  FindProgramExecutablePath(argc, argv, &app_name);
1405  }
1406  break;
1407  }
1408 
1409  return app_name;
1410 }
1411 
1412 
1414  int argc,
1415  const char* const* argv,
1416  string* real_path
1417 )
1418 {
1419  // Cache program executable path, it doesn't change during execution
1420 
1421  static CSafeStatic<string> s_Path;
1422  static CSafeStatic<string> s_RealPath;
1423  static bool s_Init = false;
1424 
1425  if (s_Init) {
1426  // Return cached value
1427  if (real_path) {
1428  *real_path = *s_RealPath;
1429  }
1430  return *s_Path;
1431  }
1432  s_Init = true;
1433 
1434  CNcbiApplicationGuard instance = InstanceGuard();
1435  string ret_val;
1436 
1437  _ASSERT(argc >= 0); // formally signed for historical reasons
1438  _ASSERT(argv != NULL || argc == 0);
1439  if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0') {
1440  ret_val = argv[0];
1441  } else if (instance) {
1442  ret_val = instance->GetArguments().GetProgramName();
1443  }
1444 
1445 #if defined(NCBI_OS_MSWIN) || defined(NCBI_OS_UNIX)
1446 
1447 # ifdef NCBI_OS_MSWIN
1448 
1449  // MS Windows: Try more accurate method of detection.
1450  try {
1451  // Load PSAPI dynamic library -- it should exist on MS-Win NT/2000/XP
1452  CDll dll_psapi("psapi.dll", CDll::eLoadNow, CDll::eAutoUnload);
1453 
1454  // Get function entry-point from DLL
1455  BOOL (STDMETHODCALLTYPE FAR * dllEnumProcessModules)
1456  (HANDLE hProcess, // handle to process
1457  HMODULE *lphModule, // array of module handles
1458  DWORD cb, // size of array
1459  LPDWORD lpcbNeeded // number of bytes required
1460  ) = NULL;
1461 
1462  dllEnumProcessModules = dll_psapi.GetEntryPoint_Func("EnumProcessModules", &dllEnumProcessModules);
1463  if ( !dllEnumProcessModules ) {
1465  }
1466 
1467  // Find executable file in the midst of all loaded modules
1468  HANDLE process = GetCurrentProcess();
1469  HMODULE module = 0;
1470  DWORD needed = 0;
1471 
1472  // Get first module of current process (it should be .exe file)
1473  if ( dllEnumProcessModules(process, &module, sizeof(HMODULE), &needed) ) {
1474  if ( needed && module ) {
1475  TXChar buf[MAX_PATH + 1];
1476  DWORD ncount = GetModuleFileName(module, buf, MAX_PATH);
1477  if (ncount > 0) {
1478  // Save to cache and return
1479  *s_Path = _T_STDSTRING(buf);
1480  *s_RealPath = CDirEntry::NormalizePath(*s_Path, eFollowLinks);
1481  if (real_path) {
1482  *real_path = *s_RealPath;
1483  }
1484  return *s_Path;
1485  }
1486  }
1487  }
1488  }
1489  catch (const CException&) {
1490  ; // Just catch an all exceptions from CDll
1491  }
1492  // This method didn't work -- use standard method
1493 # endif
1494 
1495 # ifdef NCBI_OS_LINUX
1496  // Linux OS: Try more accurate method of detection for real_path
1497  if (ret_val.empty() && !real_path) {
1498  real_path = &ret_val;
1499  }
1500  if (real_path) {
1501  char buf[PATH_MAX + 1];
1502  string procfile = "/proc/" + NStr::IntToString(getpid()) + "/exe";
1503  int ncount = (int)readlink((procfile).c_str(), buf, PATH_MAX);
1504  if (ncount > 0) {
1505  real_path->assign(buf, ncount);
1506  if (real_path == &ret_val || ret_val.empty()) {
1507  // Save to cache and return
1508  *s_Path = *real_path;
1509  *s_RealPath = *real_path;
1510  return *real_path;
1511  }
1512  real_path = 0;
1513  }
1514  }
1515 # endif
1516 
1517  if (ret_val.empty()) {
1518  // nothing to go on :-/
1519  // don't need to update cached values, they are empty
1520  if (real_path) {
1521  real_path->erase();
1522  }
1523  // This can happens on non-Windows/Linux platforms if logging is used
1524  // before CNcbiApplication initialization, and no argc/argv valuies passed in arguments.
1525  // As a fallback reset the initialization state, so it can be (maybe) initialized correctly later.
1526 #if !defined(NCBI_OS_MSWIN) && !defined(NCBI_OS_LINUX)
1527  if (argc == 0) {
1528  s_Init = false;
1529  }
1530 #endif
1531  return kEmptyStr;
1532  }
1533 
1534  // Default approach (using value from arguments):
1535 
1536  string app_path = ret_val;
1537 
1538  if ( !CDirEntry::IsAbsolutePath(app_path) ) {
1539 # ifdef NCBI_OS_MSWIN
1540  // Add default ".exe" extention to the name of executable file
1541  // if it running without extension
1542  string dir, title, ext;
1543  CDirEntry::SplitPath(app_path, &dir, &title, &ext);
1544  if ( ext.empty() ) {
1545  app_path = CDirEntry::MakePath(dir, title, "exe");
1546  }
1547 # endif
1548  if ( CFile(app_path).Exists() ) {
1549  // Relative path from the the current directory
1550  app_path = CDir::GetCwd() + CDirEntry::GetPathSeparator() + app_path;
1551  if ( !CFile(app_path).Exists() ) {
1552  app_path = kEmptyStr;
1553  }
1554  } else {
1555  // Running from some path from PATH environment variable.
1556  // Try to determine that path.
1557  string env_path;
1558  if (instance) {
1559  env_path = instance->GetEnvironment().Get("PATH");
1560  } else {
1561  env_path = _T_STDSTRING(NcbiSys_getenv(_TX("PATH")));
1562  }
1563  list<string> split_path;
1564 # ifdef NCBI_OS_MSWIN
1565  NStr::Split(env_path, ";", split_path,
1567 # else
1568  NStr::Split(env_path, ":", split_path,
1570 # endif
1571  string base_name = CDirEntry(app_path).GetBase();
1572  ITERATE(list<string>, it, split_path) {
1573  app_path = CDirEntry::MakePath(*it, base_name);
1574  if ( CFile(app_path).Exists() ) {
1575  break;
1576  }
1577  app_path = kEmptyStr;
1578  }
1579  }
1580  }
1581  ret_val = CDirEntry::NormalizePath(
1582  (app_path.empty() && argv != NULL && argv[0] != NULL) ? argv[0] : app_path);
1583 
1584 #else // defined (NCBI_OS_MSWIN) || defined(NCBI_OS_UNIX)
1585 
1586 # error "Unsupported platform, sorry -- please contact NCBI"
1587 
1588 #endif
1589 
1590  // Save to cache and return
1591  *s_Path = ret_val;
1592  *s_RealPath = CDirEntry::NormalizePath(ret_val, eFollowLinks);
1593  if (real_path) {
1594  *real_path = *s_RealPath;
1595  }
1596  return *s_Path;
1597 }
1598 
1599 
1601 {
1602  if (reg == 0) {
1603  reg = m_Config.GetPointer();
1604  if (reg == 0)
1605  return;
1606  }
1607 
1609 
1610  // [NCBI.MEMORY_FILL]
1611  CObject::SetAllocFillMode(reg->Get("NCBI", "MEMORY_FILL"));
1612 
1613  {{
1614  CSysLog* syslog = dynamic_cast<CSysLog*>(GetDiagHandler());
1615  if (syslog) {
1616  syslog->HonorRegistrySettings(reg);
1617  }
1618  }}
1619 
1620  // Debugging features
1621 
1622  // [DEBUG.DIAG_TRACE]
1623  if ( !reg->Get("DEBUG", DIAG_TRACE).empty() ) {
1625  }
1626 
1627  // [DEBUG.ABORT_ON_THROW]
1628  if ( !reg->Get("DEBUG", ABORT_ON_THROW).empty() ) {
1629  SetThrowTraceAbort(true);
1630  }
1631 
1632  // [DEBUG.DIAG_POST_LEVEL]
1633  string post_level = reg->Get("DEBUG", DIAG_POST_LEVEL);
1634  if ( !post_level.empty() ) {
1635  EDiagSev sev;
1636  if (CNcbiDiag::StrToSeverityLevel(post_level.c_str(), sev)) {
1637  SetDiagFixedPostLevel(sev);
1638  }
1639  }
1640 
1641  // [DEBUG.MessageFile]
1642  string msg_file = reg->Get("DEBUG", DIAG_MESSAGE_FILE);
1643  if ( !msg_file.empty() ) {
1645  if ( !info || !info->Read(msg_file) ) {
1646  if ( info ) {
1647  delete info;
1648  }
1649  ERR_POST_X(12, Warning << "Applications message file \""
1650  << msg_file
1651  << "\" is not found");
1652  } else {
1654  }
1655  }
1656 
1657  // [DEBUG.GuardAgainstThreadsOnStaticDataDestruction]
1658  if ( !reg->GetBool("DEBUG", "GuardAgainstThreadsOnStaticDataDestruction", true, 0, IRegistry::eErrPost) ) {
1660  }
1661 
1662  // CPU and memory limitations
1663 
1664  // [NCBI.HeapSizeLimit]
1665  if ( !reg->Get("NCBI", "HeapSizeLimit").empty() ) {
1666  ERR_POST_X(13, Warning
1667  << "Config param [NCBI.HeapSizeLimit] is deprecated,"
1668  << "please use [NCBI.MemorySizeLimit] instead.");
1669  int mem_size_limit = reg->GetInt("NCBI", "HeapSizeLimit", 0);
1670  if (mem_size_limit < 0) {
1671  NCBI_THROW(CAppException, eLoadConfig,
1672  "Configuration file error: [NCBI.HeapSizeLimit] < 0");
1673  }
1674  SetMemoryLimit(size_t(mem_size_limit) * 1024 * 1024);
1675  }
1676  // [NCBI.MemorySizeLimit]
1677  if ( !reg->Get("NCBI", "MemorySizeLimit").empty() ) {
1678  size_t mem_size_limit = 0;
1679  string s = reg->GetString("NCBI", "MemorySizeLimit", kEmptyStr);
1680  size_t pos = s.find("%");
1681  if (pos != NPOS) {
1682  // Size in percents of total memory
1683  size_t percents = NStr::StringToUInt(CTempString(s, 0, pos));
1684  if (percents > 100) {
1685  NCBI_THROW(CAppException, eLoadConfig,
1686  "Configuration file error: [NCBI.HeapSizeLimit] > 100%");
1687  }
1688  mem_size_limit = (size_t)(CSystemInfo::GetTotalPhysicalMemorySize() * percents / 100);
1689  } else {
1690  try {
1691  // Size is specified in MiB by default if no suffixes
1692  // (converted without exception)
1693  mem_size_limit = NStr::StringToSizet(s) * 1024 * 1024;
1694  }
1695  catch (const CStringException&) {
1696  // Otherwise, size have suffix (MiB, G, GB, etc)
1698  if ( bytes > get_limits(mem_size_limit).max() ) {
1699  NCBI_THROW(CAppException, eLoadConfig,
1700  "Configuration file error: [NCBI.MemorySizeLimit] is too big");
1701  }
1702  mem_size_limit = (size_t)bytes;
1703  }
1704  }
1705  SetMemoryLimit(mem_size_limit);
1706  }
1707 
1708  // [NCBI.CpuTimeLimit]
1709  if ( !reg->Get("NCBI", "CpuTimeLimit").empty() ) {
1710  int cpu_time_limit = reg->GetInt("NCBI", "CpuTimeLimit", 0);
1711  if (cpu_time_limit < 0) {
1712  NCBI_THROW(CAppException, eLoadConfig,
1713  "Configuration file error: [NCBI.CpuTimeLimit] < 0");
1714  }
1715  SetCpuTimeLimit((unsigned int)cpu_time_limit, 5, NULL, NULL);
1716  }
1717 
1718  // TRACE and POST filters
1719 
1720  try {
1721  // [DIAG.TRACE_FILTER]
1722  string trace_filter = reg->Get("DIAG", "TRACE_FILTER");
1723  if ( !trace_filter.empty() )
1724  SetDiagFilter(eDiagFilter_Trace, trace_filter.c_str());
1725  } NCBI_CATCH_X(20,
1726  "Failed to load and set diag. filter for traces");
1727 
1728  try {
1729  // [DIAG.POST_FILTER]
1730  string post_filter = reg->Get("DIAG", "POST_FILTER");
1731  if ( !post_filter.empty() )
1732  SetDiagFilter(eDiagFilter_Post, post_filter.c_str());
1733  } NCBI_CATCH_X(21,
1734  "Failed to load and set diag. filter for regular errors");
1735 }
1736 
1737 
1739 {
1740  string cmd_line = GetProgramExecutablePath();
1741  if ( m_Arguments.get() ) {
1742  if ( cmd_line.empty() ) {
1743  cmd_line = (*m_Arguments)[0];
1744  }
1745  for (SIZE_TYPE arg = 1; arg < m_Arguments->Size(); ++arg) {
1746  cmd_line += " ";
1747  cmd_line += NStr::ShellEncode((*m_Arguments)[arg]);
1748  }
1749  }
1750 
1751  // Print application start message
1753  GetDiagContext().PrintStart(cmd_line);
1754  }
1755 }
1756 
1757 
1758 void CNcbiApplicationAPI::AppStop(int exit_code)
1759 {
1761  if ( !ctx.IsSetExitCode() ) {
1762  ctx.SetExitCode(exit_code);
1763  }
1764 }
1765 
1766 
1768 {
1769  m_ExitCode = exit_code;
1770  m_ExitCodeCond = when;
1771 }
1772 
1773 const char* CAppException::GetErrCodeString(void) const
1774 {
1775  switch (GetErrCode()) {
1776  case eUnsetArgs: return "eUnsetArgs";
1777  case eSetupDiag: return "eSetupDiag";
1778  case eLoadConfig: return "eLoadConfig";
1779  case eSecond: return "eSecond";
1780  case eNoRegistry: return "eNoRegistry";
1781  default: return CException::GetErrCodeString();
1782  }
1783 }
1784 
1785 
1787 {
1789 }
1790 
1791 
1793 {
1794 public:
1797 
1799  void SetIdler(INcbiIdler* idler, EOwnership own);
1800  void RunIdler(void);
1801 
1802 private:
1805 };
1806 
1807 
1808 inline
1810 {
1811  CMutexGuard guard(m_Mutex);
1812  m_Idler.reset(m_Idler.release(), own);
1813  return m_Idler.get();
1814 }
1815 
1816 
1817 inline
1819 {
1820  CMutexGuard guard(m_Mutex);
1821  m_Idler.reset(idler, own);
1822 }
1823 
1824 
1825 inline
1827 {
1828  if ( m_Idler.get() ) {
1829  CMutexGuard guard(m_Mutex);
1830  if ( m_Idler.get() ) {
1831  m_Idler->Idle();
1832  }
1833  }
1834 }
1835 
1836 
1838 
1840 {
1841  return s_IdlerWrapper.Get().GetIdler(ownership);
1842 }
1843 
1844 
1845 void SetIdler(INcbiIdler* idler, EOwnership ownership)
1846 {
1847  s_IdlerWrapper.Get().SetIdler(idler, ownership);
1848 }
1849 
1850 
1851 void RunIdler(void)
1852 {
1853  s_IdlerWrapper.Get().RunIdler();
1854 }
1855 
1856 
ncbi::TMaskedQueryRegions mask
AutoArray –.
Definition: ncbimisc.hpp:527
CAppException –.
Definition: ncbiapp_api.hpp:77
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgException –.
Definition: ncbiargs.hpp:120
CArgHelpException –.
Definition: ncbiargs.hpp:158
CArgs –.
Definition: ncbiargs.hpp:379
CCoreException –.
Definition: ncbiexpt.hpp:1476
Default idler.
Temporary object for holding extra message arguments.
Definition: ncbidiag.hpp:1828
CDiagErrCodeInfo –.
Definition: ncbidiag.hpp:3029
CDirEntry –.
Definition: ncbifile.hpp:262
CDll –.
Definition: ncbidll.hpp:107
CFile –.
Definition: ncbifile.hpp:1604
void RunIdler(void)
Definition: ncbiapp.cpp:1826
CIdlerWrapper(void)
Definition: ncbiapp.cpp:1795
AutoPtr< INcbiIdler > m_Idler
Definition: ncbiapp.cpp:1804
~CIdlerWrapper(void)
Definition: ncbiapp.cpp:1796
INcbiIdler * GetIdler(EOwnership own)
Definition: ncbiapp.cpp:1809
void SetIdler(INcbiIdler *idler, EOwnership own)
Definition: ncbiapp.cpp:1818
CMutex m_Mutex
Definition: ncbiapp.cpp:1803
static SEntry Load(const string &name, ENameStyle style=eName_AsIs, TFlags flags=0, TRegFlags reg_flags=0, IRWRegistry *reg=0, const string &path=kEmptyStr)
Load the configuration file "name".
Definition: metareg.cpp:139
@ eName_RcOrIni
C Toolkit style; mostly useful with name = "ncbi".
Definition: metareg.hpp:66
@ eName_AsIs
Take the specified filename as is.
Definition: metareg.hpp:61
@ eName_Ini
Add .ini, dropping existing extensions as needed.
Definition: metareg.hpp:62
static string FindRegistry(const string &name, ENameStyle style=eName_AsIs)
Yield the path to a registry with the given name if available, or the empty string otherwise.
Definition: metareg.hpp:251
CMutex –.
Definition: ncbimtx.hpp:749
CNcbiApplicationAPI –.
static CNcbiApplication * Instance(void)
Singleton method.
Definition: ncbiapp.cpp:264
CNcbiApplication(const SBuildInfo &build_info=NCBI_SBUILDINFO_DEFAULT())
Constructor.
Definition: ncbiapp.cpp:270
virtual ~CNcbiApplication(void)
Destructor.
Definition: ncbiapp.cpp:276
CNcbiArguments –.
Definition: ncbienv.hpp:236
CNcbiEnvironment –.
Definition: ncbienv.hpp:110
CNcbiRegistry –.
Definition: ncbireg.hpp:913
CRWLock –.
Definition: ncbimtx.hpp:953
static void Destroy(CSafeStaticLifeSpan::ELifeLevel level)
Explicitly destroy all on-demand variables up to a specified level.
static void DisableChildThreadsCheck()
Disable checking on child thread(s) running during destruction.
CSafeStaticLifeSpan::
@ eLifeLevel_AppMain
Destroyed in CNcbiApplication::AppMain, if possible.
CSafeStatic<>::
static void s_HonorSignalHandlingConfiguration(void)
Definition: ncbi_stack.cpp:189
CStreamDiagHandler –.
Definition: ncbidiag.hpp:2596
CStringException –.
Definition: ncbistr.hpp:4506
static Uint8 GetTotalPhysicalMemorySize(void)
Return the amount of actual/total physical memory, in bytes.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CVersionInfo –.
Interface for application idler.
Interface class for Phone Home Policy.
IRWRegistry –.
Definition: ncbireg.hpp:407
IRegistry –.
Definition: ncbireg.hpp:73
void Print(const CCompactSAMApplication::AlignInfo &ai)
constexpr auto begin(const ct_const_array< T, N > &in) noexcept
string Path(const string &dir, const string &file)
Definition: fileutil.cpp:243
CS_CONTEXT * ctx
Definition: t0006.c:12
#define false
Definition: bool.h:36
static void fatal(const char *msg,...)
Definition: attributes.c:18
static const char * str(char *buf, int n)
Definition: stats.c:84
static HENV env
Definition: transaction2.c:38
#define basename(path)
Definition: replacements.h:116
void x_LogOptions(int event)
Log environment, registry, command arguments, path.
Definition: ncbiapp.cpp:561
unique_ptr< CNcbiArguments > m_Arguments
Command-line arguments.
virtual EPreparseArgs PreparseArgs(int argc, const char *const *argv)
Check the command line arguments before parsing them.
Definition: ncbiapp.cpp:1299
CNcbiApplicationAPI * m_App
void SetFullVersion(CRef< CVersionAPI > version)
Set version data for the program.
Definition: ncbiapp.cpp:1174
int TStdioSetupFlags
Binary OR of "EStdioSetup".
void reset(element_type *p=0, EOwnership ownership=eTakeOwnership)
Reset will delete the old pointer (if owned), set content to the new value, and assume the ownership ...
Definition: ncbimisc.hpp:480
void ExecuteActions(void)
Definition: ncbimisc.hpp:1397
SIZE_TYPE FlushDiag(CNcbiOstream *os, bool close_diag=false)
Flush the in-memory diagnostic stream (for "eDS_ToMemory" case only).
Definition: ncbiapp.cpp:315
string m_ConfigPath
Path to .ini file used.
CNcbiActionGuard m_OnExitActions
Actions executed on app destruction.
bool SetupDiag(EAppDiagStream diag)
Setup the application diagnostic stream.
Definition: ncbiapp.cpp:1212
TDisableArgDesc m_DisableArgDesc
Arg desc. disabled.
void HideStdArgs(THideStdArgs hide_mask)
Set the hide mask for the Hide Std Flags.
Definition: ncbiapp.cpp:1312
TStdioSetupFlags m_StdioFlags
Std C++ I/O adjustments.
static string GetAppName(EAppNameType name_type=eBaseName, int argc=0, const char *const *argv=NULL)
Definition: ncbiapp.cpp:1377
friend class CNcbiApplicationGuard
void x_TryMain(EAppDiagStream diag, const char *conf, int *exit_code, bool *got_exception)
Definition: ncbiapp.cpp:649
void x_TryInit(EAppDiagStream diag, const char *conf)
Definition: ncbiapp.cpp:413
string m_ProgramDisplayName
Display name of app.
void x_SetupStdio(void)
Setup C++ standard I/O streams' behaviour.
Definition: ncbiapp.cpp:1327
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
Definition: ncbiapp.cpp:1773
void ExecuteOnExitActions()
Should only be called from the destructors of classes derived from CNcbiApplicationAPI - if it is nec...
Definition: ncbiapp.cpp:206
virtual int Run(void)=0
Run the application.
int m_LogOptions
logging of env, reg, args, path
IPhoneHomePolicy * m_PhoneHomePolicy
Pointer to active Phone Home Policy, if any.
string m_ExePath
Program executable path.
const CNcbiEnvironment & GetEnvironment(void) const
Get the application's cached environment.
CNcbiEnvironment & SetEnvironment(void)
Get a non-const copy of the application's cached environment.
const string & GetProgramExecutablePath(EFollowLinks follow_links=eIgnoreLinks) const
Get the application's executable path.
static CNcbiApplicationGuard InstanceGuard(void)
Singleton method.
Definition: ncbiapp.cpp:133
virtual void Init(void)
Initialize the application.
Definition: ncbiapp.cpp:286
EExitMode
When to return a user-set exit code.
virtual void AppStop(int exit_code)
Method to be called before application exit.
Definition: ncbiapp.cpp:1758
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
~CNcbiApplicationGuard(void)
Definition: ncbiapp.cpp:104
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
Definition: ncbiapp.cpp:305
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:819
CVersionInfo GetVersion(void) const
Get the program version information.
Definition: ncbiapp.cpp:1184
virtual bool SetupDiag_AppSpecific(void)
Setup application specific diagnostic stream.
Definition: ncbiapp.cpp:1219
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1195
int m_ExitCode
Exit code to force.
char * m_CinBuffer
Cin buffer if changed.
EPreparseArgs
Result of PreparseArgs()
static CNcbiApplicationAPI * Instance(void)
Singleton method.
Definition: ncbiapp.cpp:127
virtual bool LoadConfig(CNcbiRegistry &reg, const string *conf, CNcbiRegistry::TFlags reg_flags)
Load settings from the configuration file to the registry.
Definition: ncbiapp.cpp:1226
INcbiIdler * GetIdler(EOwnership ownership)
Return currently installed idler or NULL.
Definition: ncbiapp.cpp:1839
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
const char * m_LogFile
Logfile if set in the command line.
bool m_DryRun
Dry run.
void SetStdioFlags(TStdioSetupFlags stdio_flags)
Adjust the behavior of standard I/O streams.
Definition: ncbiapp.cpp:1318
shared_ptr< CReadLockGuard > m_AppLock
unique_ptr< CNcbiEnvironment > m_Environ
Cached application env.
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:469
void SetVersionByBuild(int major)
Definition: ncbiapp.cpp:1148
unique_ptr< CArgs > m_Args
Parsed cmd.-line args.
int THideStdArgs
Binary OR of "EHideStdArgs".
virtual void Exit(void)
Cleanup on application exit.
Definition: ncbiapp.cpp:299
void x_AddDefaultArgs(void)
Definition: ncbiapp.cpp:1356
CNcbiApplicationGuard(CNcbiApplicationAPI *app)
Definition: ncbiapp.cpp:96
static string FindProgramExecutablePath(int argc, const char *const *argv, string *real_path=0)
Find the application's executable file.
Definition: ncbiapp.cpp:1413
virtual void Apply(CNcbiApplicationAPI *app)=0
Apply policy for an application.
const string & GetProgramDisplayName(void) const
Get the application's "display" name.
EExitMode m_ExitCodeCond
When to force it (if ever)
void DisableArgDescriptions(TDisableArgDesc disable=fDisableStdArgs)
Definition: ncbiapp.cpp:1306
virtual void AppStart(void)
Method to be called before application start.
Definition: ncbiapp.cpp:1738
static CRWLock & GetInstanceLock(void)
Definition: ncbiapp.cpp:119
unique_ptr< CArgDescriptions > m_ArgDesc
Cmd.-line arg descriptions.
virtual void Idle(void)=0
int TDisableArgDesc
Binary OR of "EDisableArgDesc".
CRef< CNcbiRegistry > m_Config
Guaranteed to be non-NULL.
static SSystemMutex & GetInstanceMutex(void)
Mutex for application singleton object.
Definition: ncbiapp.cpp:111
static CNcbiApplicationAPI * m_Instance
Current app. instance.
virtual int DryRun(void)
Test run the application.
Definition: ncbiapp.cpp:292
void SetProgramDisplayName(const string &app_name)
Set program's display name.
Definition: ncbiapp.cpp:1366
const CVersionAPI & GetFullVersion(void) const
Get the program version information.
Definition: ncbiapp.cpp:1189
ENcbiOwnership m_PhoneHomePolicy_Ownership
Phone Home Policy ownersheep.
void SetIdler(INcbiIdler *idler, EOwnership ownership)
Set new idler and ownership.
Definition: ncbiapp.cpp:1845
string m_RealExePath
Symlink-free executable path.
virtual void Idle(void)
Definition: ncbiapp.cpp:1786
virtual ~CNcbiApplicationAPI(void)
Destructor.
Definition: ncbiapp.cpp:227
virtual void Finish()
Deinitialize policy/reporting API.
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:581
const CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
void RunIdler(void)
Execute currently installed idler if any.
Definition: ncbiapp.cpp:1851
void SetPhoneHomePolicy(IPhoneHomePolicy *policy, ENcbiOwnership ownership=eNoOwnership)
Set Phone Home Policy.
Definition: ncbiapp.cpp:212
bool m_ConfigLoaded
Finished loading config.
THideStdArgs m_HideArgs
Std cmd.-line flags to hide.
element_type * release(void)
Release will release ownership of pointer to caller.
Definition: ncbimisc.hpp:472
void SetExitCode(int exit_code, EExitMode when=eExceptionalExits)
Force the program to return a specific exit code later, either when it exits due to an exception or u...
Definition: ncbiapp.cpp:1767
void SetVersion(const CVersionInfo &version)
Set the version number for the program.
Definition: ncbiapp.cpp:1155
string m_DefaultConfig
conf parameter to AppMain
CNcbiApplicationAPI(const SBuildInfo &build_info)
Constructor.
Definition: ncbiapp.cpp:139
void x_HonorStandardSettings(IRegistry *reg=0)
Read standard NCBI application configuration settings.
Definition: ncbiapp.cpp:1600
CRef< CVersionAPI > m_Version
Program version.
void x_ReadLogOptions()
Read switches that are stored in m_LogOptions from registry and environment.
Definition: ncbiapp.cpp:506
@ fHideFullHelp
Hide full help description.
@ fHideFullVersion
Hide full version description.
@ fHideAll
Hide all standard argument descriptions.
@ fHideHelp
Hide help description.
@ fHideVersion
Hide version description.
@ eAllExits
always (ignoring Run's return value)
@ eNoExits
never (stick to existing logic)
@ eExceptionalExits
when an (uncaught) exception occurs
@ fBinaryCout
treat standard output as binary
@ fNoSyncWithStdio
Turn off synchronizing of "C++" cin/cout/cerr streams with their "C" counterparts,...
@ fDefault_CinBufferSize
Use compiler-specific default of Cin buffer size.
@ fBinaryCin
treat standard input as binary
@ ePreparse_Exit
Exit the application with zero exit code.
@ ePreparse_Continue
Continue application execution.
@ eNoRegistry
Registry file cannot be opened.
Definition: ncbiapp_api.hpp:87
@ eUnsetArgs
Command-line argument description not found.
Definition: ncbiapp_api.hpp:83
@ eSecond
Second instance of CNcbiApplicationAPI is prohibited.
Definition: ncbiapp_api.hpp:86
@ eLoadConfig
Registry data failed to load from config file.
Definition: ncbiapp_api.hpp:85
@ eSetupDiag
Application diagnostic stream setup failed.
Definition: ncbiapp_api.hpp:84
@ eIgnoreLinks
Do not follow symbolic links.
Definition: ncbimisc.hpp:144
@ eFollowLinks
Follow symbolic links.
Definition: ncbimisc.hpp:145
@ eFullName
per GetProgramExecutablePath(eIgnoreLinks)
@ eRealName
per GetProgramExecutablePath(eFollowLinks)
@ eBaseName
per GetProgramDisplayName
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
CArgs * CreateArgs(TSize argc, TArray argv) const
Create parsed arguments in CArgs object.
Definition: ncbiargs.hpp:1279
@ eHelpShowAll
Error code for detailed help message which includes hidden arguments.
Definition: ncbiargs.hpp:164
@ eHelpErr
Show short help message and return error.
Definition: ncbiargs.hpp:166
@ eHelpXml
Error code for XML formatted help message.
Definition: ncbiargs.hpp:165
@ eHelpFull
Error code for detailed help message.
Definition: ncbiargs.hpp:163
@ fNoUsage
Do not print USAGE on argument error.
Definition: ncbiargs.hpp:1028
@ fDupErrToCerr
Print arg error to both log and cerr.
Definition: ncbiargs.hpp:1032
@ eNoValue
Expecting an argument value.
Definition: ncbiargs.hpp:128
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define FAR
Definition: ncbistd.hpp:278
#define _TRACE(message)
Definition: ncbidbg.hpp:122
void SetDiagFilter(EDiagFilter what, const char *filter_str)
Set diagnostic filter.
Definition: ncbidiag.cpp:7670
CDiagContext_Extra & Print(const string &name, const string &value)
The method does not print the argument, but adds it to the string.
Definition: ncbidiag.cpp:2622
static bool IsSetOldPostFormat(void)
Check old/new format flag (for compatibility only)
Definition: ncbidiag.cpp:3346
void PrintStart(const string &message)
Print start/stop etc.
Definition: ncbidiag.cpp:2095
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
static void SetRequestContext(CRequestContext *ctx)
Shortcut to CDiagContextThreadData::GetThreadData().SetRequestContext()
Definition: ncbidiag.cpp:1907
void SetDiagFixedPostLevel(EDiagSev post_sev)
Sets and locks the level, combining the previous two calls.
Definition: ncbidiag.cpp:6179
void DiagHandler_Reopen(void)
Ask diagnostic handler to reopen log files if necessary.
Definition: ncbidiag.cpp:6344
CDiagContext_Extra Extra(void) const
Create a temporary CDiagContext_Extra object.
Definition: ncbidiag.hpp:2095
bool IsSetExitCode(void) const
Check if exit code has been set.
Definition: ncbidiag.hpp:2172
TUID GetUID(void) const
Return (create if not created yet) unique diagnostic ID.
Definition: ncbidiag.cpp:1664
EAppDiagStream
Where to write the application's diagnostics to.
Definition: ncbidiag.hpp:1780
#define DIAG_POST_LEVEL
Diagnostic post severity level.
Definition: ncbidiag.hpp:1447
void FlushMessages(CDiagHandler &handler)
Flush the collected messages to the current diag handler.
Definition: ncbidiag.cpp:3387
void SetAppName(const string &app_name)
Set application name.
Definition: ncbidiag.cpp:1884
void DiscardMessages(void)
Discard the collected messages without printing them.
Definition: ncbidiag.cpp:3411
CDiagHandler * GetDiagHandler(bool take_ownership=false, bool *current_ownership=0)
Get the currently set diagnostic handler class.
Definition: ncbidiag.cpp:6329
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
Definition: ncbidiag.cpp:8147
void SetDiagErrCodeInfo(CDiagErrCodeInfo *info, bool can_delete=true)
Set handler for processing error codes.
Definition: ncbidiag.cpp:7644
void SetExitCode(int exit_code)
Set exit code.
Definition: ncbidiag.hpp:2176
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
virtual CNcbiOstream * GetStream(void)
Definition: ncbidiag.hpp:2612
static void x_FinalizeSetupDiag(void)
Internal function, should be used only by CNcbiApplication.
Definition: ncbidiag.cpp:3501
static void SetupDiag(EAppDiagStream ds=eDS_Default, CNcbiRegistry *config=NULL, EDiagCollectMessages collect=eDCM_NoChange, const char *cmd_logfile=NULL)
Application-wide diagnostics setup.
Definition: ncbidiag.cpp:3545
void InitMessages(size_t max_size=100)
Start collecting all messages (the collected messages can be flushed to a new destination later).
Definition: ncbidiag.cpp:3370
void SetDiagTrace(EDiagTrace how, EDiagTrace dflt=eDT_Default)
Set the diagnostic trace settings.
Definition: ncbidiag.cpp:6226
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
TDiagPostFlags SetDiagPostAllFlags(TDiagPostFlags flags)
Set global post flags to "flags".
Definition: ncbidiag.cpp:6065
#define DIAG_MESSAGE_FILE
Diagnostic message file.
Definition: ncbidiag.hpp:3092
#define DIAG_TRACE
Diagnostic trace setting.
Definition: ncbidiag.hpp:1540
static bool StrToSeverityLevel(const char *str_sev, EDiagSev &sev)
Get severity from string.
Definition: ncbidiag.cpp:7904
void SetDiagStream(CNcbiOstream *os, bool quick_flush=true, FDiagCleanup cleanup=0, void *cleanup_data=0, const string &stream_name="")
Set diagnostic stream.
Definition: ncbidiag.cpp:8083
void SetGlobalAppState(EDiagAppState state)
Set global application state.
Definition: ncbidiag.cpp:2809
void HonorRegistrySettings(const IRegistry *reg=0)
Definition: syslog.cpp:252
@ eDPF_Severity
Severity (default)
Definition: ncbidiag.hpp:697
@ eDCM_NoChange
Continue collecting messages if already started.
Definition: ncbidiag.hpp:1803
@ eDCM_Flush
Flush the collected messages and stop collecting.
Definition: ncbidiag.hpp:1804
@ eDS_User
Leave as was previously set (or not set) by user.
Definition: ncbidiag.hpp:1787
@ eDS_ToStderr
To standard error stream.
Definition: ncbidiag.hpp:1782
@ eDT_Enable
Enable messages of severity "eDiag_Trace".
Definition: ncbidiag.hpp:1550
@ eDiagAppState_AppEnd
AE.
Definition: ncbidiag.hpp:793
@ eDiagAppState_AppBegin
AB.
Definition: ncbidiag.hpp:791
@ eDiagAppState_AppRun
A.
Definition: ncbidiag.hpp:792
@ eDiagFilter_Post
for all non-TRACE, non-FATAL
Definition: ncbidiag.hpp:2530
@ eDiagFilter_Trace
for TRACEs only
Definition: ncbidiag.hpp:2529
TFunc GetEntryPoint_Func(const string &name, TFunc *func)
Get DLLs entry point (function).
Definition: ncbidll.hpp:273
@ eAutoUnload
Definition: ncbidll.hpp:144
@ eLoadNow
Definition: ncbidll.hpp:138
void Set(const string &name, const string &value)
Set an environment variable by name.
Definition: ncbienv.cpp:147
const string & Get(const string &name, bool *found=NULL) const
Get environment value by name.
Definition: ncbienv.cpp:109
const string & GetProgramName(EFollowLinks follow_links=eIgnoreLinks) const
Get program name.
Definition: ncbienv.cpp:373
void Critical(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1203
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#define NCBI_RETHROW_SAME(prev_exception, message)
Generic macro to re-throw the same exception.
Definition: ncbiexpt.hpp:749
#define NCBI_CATCH_X(err_subcode, message)
Catch CExceptions as well with default error code and given error subcode placed in diagnostics.
Definition: ncbiexpt.hpp:615
CRequestContext & GetRequestContext(void) const
Get the request context in which the exception was thrown.
Definition: ncbiexpt.cpp:472
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
void Fatal(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1209
int TErrCode
Definition: ncbiexpt.hpp:889
#define ABORT_ON_THROW
ABORT_ON_THROW controls if program should be aborted.
Definition: ncbiexpt.hpp:80
TErrCode GetErrCode(void) const
Definition: ncbiexpt.hpp:1493
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
Definition: ncbiexpt.cpp:444
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
#define NCBI_REPORT_EXCEPTION_X(err_subcode, title, ex)
Generate a report on the exception with default error code and given subcode.
Definition: ncbiexpt.hpp:761
#define NCBI_RETHROW(prev_exception, exception_class, err_code, message)
Generic macro to re-throw an exception.
Definition: ncbiexpt.hpp:737
void SetThrowTraceAbort(bool abort_on_throw_trace)
Specify whether to call "abort()" inside the DoThrowTraceAbort().
Definition: ncbiexpt.cpp:66
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
static string NormalizePath(const string &path, EFollowLinks follow_links=eIgnoreLinks)
Normalize a path.
Definition: ncbifile.cpp:820
static bool IsAbsolutePath(const string &path)
Check if a "path" is absolute for the current OS.
Definition: ncbifile.cpp:508
string GetBase(void) const
Get the base entry name without extension.
Definition: ncbifile.hpp:3924
static string MakePath(const string &dir=kEmptyStr, const string &base=kEmptyStr, const string &ext=kEmptyStr)
Assemble a path from basic components.
Definition: ncbifile.cpp:413
static char GetPathSeparator(void)
Get path separator symbol specific for the current platform.
Definition: ncbifile.cpp:433
static string GetCwd(void)
Get the current working directory.
Definition: ncbifile.cpp:3708
string GetName(void) const
Get the base entry name with extension (if any).
Definition: ncbifile.hpp:3916
#define PATH_MAX
Definition: ncbifile.hpp:106
static void SplitPath(const string &path, string *dir=0, string *base=0, string *ext=0)
Split a path string into its basic components.
Definition: ncbifile.cpp:358
static void SetAllocFillMode(EAllocFillMode mode)
Definition: ncbiobj.cpp:436
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
#define kMax_Int
Definition: ncbi_limits.h:184
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
ncbi_numeric_limits< T > get_limits(const T &)
Generic template to get STD limits by a variable.
size_t resident_peak
Peak resident set size ("high water mark")
size_t total_peak
Peak total memory usage.
size_t resident
Resident/working set size (RSS).
size_t total
Total memory usage.
size_t shared
Shared memory usage.
static bool GetMemoryUsage(SMemoryUsage &usage)
Get current process memory usage.
size_t data
Data segment size.
static bool GetTimes(double *real, double *user, double *sys, EWhat what=eProcess)
Get current process execution times.
size_t stack
Stack size of the initial thread in the process.
@ eChildren
All children of the calling process.
@ eThread
Current thread.
@ eProcess
Current process.
int TFlags
Binary OR of "EFlags".
Definition: ncbireg.hpp:107
virtual bool GetBool(const string &section, const string &name, bool default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get boolean value of specified parameter name.
Definition: ncbireg.cpp:391
virtual void EnumerateSections(list< string > *sections, TFlags flags=fAllLayers) const
Enumerate section names.
Definition: ncbireg.cpp:497
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
virtual int GetInt(const string &section, const string &name, int default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get integer value of specified parameter name.
Definition: ncbireg.cpp:362
bool Empty(TFlags flags=fAllLayers) const
Verify if Registry is empty.
Definition: ncbireg.cpp:162
bool IncludeNcbircIfAllowed(TFlags flags=fWithNcbirc)
Attempt to load a systemwide configuration file (.ncbirc on Unix, ncbi.ini on Windows) as a low-prior...
Definition: ncbireg.cpp:1634
virtual void EnumerateEntries(const string &section, list< string > *entries, TFlags flags=fAllLayers) const
Enumerate parameter names for a specified section.
Definition: ncbireg.cpp:514
IRWRegistry * Read(CNcbiIstream &is, TFlags flags=0, const string &path=kEmptyStr)
Read and parse the stream "is", and merge its content with current Registry entries.
Definition: ncbireg.cpp:605
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
bool Write(CNcbiOstream &os, TFlags flags=0) const
Write the registry content to output stream.
Definition: ncbireg.cpp:196
void Clear(TFlags flags=fAllLayers)
Reset the registry content.
Definition: ncbireg.cpp:590
@ fWithNcbirc
Include .ncbirc (used only by CNcbiReg.)
Definition: ncbireg.hpp:93
@ eErrPost
Log the error message and return default value.
Definition: ncbireg.hpp:202
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
#define NcbiCout
Definition: ncbistre.hpp:543
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
#define NcbiEmptyCStr
Definition: ncbistr.hpp:59
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NcbiEmptyXCStr
Definition: ncbistr.hpp:184
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
#define NcbiEmptyXString
Definition: ncbistr.hpp:185
char TXChar
Definition: ncbistr.hpp:172
static int strcmp(const char *s1, const char *s2)
String compare.
Definition: ncbistr.hpp:5208
static Uint8 StringToUInt8_DataSize(const CTempString str, TStringToNumFlags flags=0)
Convert string that can contain "software" qualifiers to Uint8.
Definition: ncbistr.cpp:1539
#define NPOS
Definition: ncbistr.hpp:133
static size_t StringToSizet(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to size_t.
Definition: ncbistr.cpp:1769
string TXString
Definition: ncbistr.hpp:173
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
#define _T_STDSTRING(x)
Definition: ncbistr.hpp:180
#define _T_CSTRING(x)
Definition: ncbistr.hpp:182
#define NcbiEmptyString
Definition: ncbistr.hpp:122
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
#define _TX(x)
Definition: ncbistr.hpp:176
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
Definition: ncbistr.cpp:642
static int strncmp(const char *s1, const char *s2, size_t n)
String compare up to specified number of characters.
Definition: ncbistr.hpp:5214
static string ShellEncode(const string &str)
Quotes a string in Bourne Again Shell (BASH) syntax, in a way that disallows non-printable characters...
Definition: ncbistr.cpp:4680
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
static bool WaitForAllThreads(void)
Definition: ncbithr.cpp:974
static void InitializeMainThreadId(void)
Initialize main thread's TID.
Definition: ncbithr.cpp:482
static bool sm_IsExiting
Definition: ncbithr.hpp:660
enum ENcbiOwnership EOwnership
Ownership relations between objects.
ENcbiOwnership
Ownership relations between objects.
Definition: ncbi_types.h:134
string GetExtraValue(EExtra key, const string &default_value=kEmptyStr) const
Definition: version.cpp:464
void SetVersionInfo(int ver_major, int ver_minor, int patch_level=0, const string &ver_name=kEmptyStr)
Set version information.
Definition: version.cpp:648
const SBuildInfo & GetBuildInfo() const
Get build info (date and tag, if set)
Definition: version.cpp:695
const CVersionInfo & GetVersionInfo() const
Get version information.
Definition: version.cpp:676
static CVersionInfo GetPackageVersion(void)
Definition: version.cpp:705
#define NCBI_APP_SBUILDINFO_DEFAULT()
Definition: version.hpp:121
string Print(const string &appname, TPrintFlags flags=fPrintAll) const
Print version data, plain text.
Definition: version.cpp:718
bool IsAny() const
Check if version is all zero (major, minor, patch) Convention is that all-zero version used in reques...
string PrintXml(const string &appname, TPrintFlags flags=fPrintAll) const
Print version data, XML.
Definition: version.cpp:764
void AddComponentVersion(const string &component_name, int ver_major, int ver_minor, int patch_level, const string &ver_name, const SBuildInfo &build_info)
Add component version information.
Definition: version.cpp:681
string PrintJson(const string &appname, TPrintFlags flags=fPrintAll) const
Print version data, JSON.
Definition: version.cpp:814
@ fPackageShort
Print package info, if available.
@ fVersionInfo
Print version info.
@ eTeamCityBuildNumber
Definition: version_api.hpp:69
@ eTeamCityProjectName
Definition: version_api.hpp:67
@ eStableComponentsVersion
Definition: version_api.hpp:72
#define HANDLE
An abstraction for a file handle.
Definition: mdb.c:383
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
Definition of all error codes used in corelib (xncbi.lib).
char * buf
int i
static MDB_envinfo info
Definition: mdb_load.c:37
static int version
Definition: mdb_load.c:29
constexpr bool empty(list< Ts... >) noexcept
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
static string s_Path
Directory for all database files of the storage.
Definition: nc_storage.cpp:215
#define strdup
Definition: ncbi_ansi_ext.h:70
#define NCBI_SC_VERSION_PROXY
#define NCBI_TEAMCITY_PROJECT_NAME_PROXY
#define NCBI_TEAMCITY_BUILD_NUMBER_PROXY
#define NCBI_SUBVERSION_REVISION_PROXY
unsigned int a
Definition: ncbi_localip.c:102
Defines MS Windows specifics for our "C++" code.
Static variables safety - create on demand, destroy on application termination.
bool SetCpuTimeLimit(unsigned int max_cpu_time, unsigned int terminate_delay_time, TLimitsPrintHandler handler, TLimitsPrintParameter parameter)
[UNIX only] Set CPU time usage limit.
@ fSuppress_Exception
Unhandled exceptions.
bool SetMemoryLimit(size_t max_size, TLimitsPrintHandler handler=NULL, TLimitsPrintParameter parameter=NULL)
[UNIX only] Set memory limit.
bool VerifyCpuCompatibility(string *message=nullptr)
Verify that the CPU, where an application run, is compatible with flags it compiled for.
void SuppressSystemMessageBox(TSuppressSystemMessageBox mode=fSuppress_Default)
Suppress popup messages on execution errors.
CSafeStatic< CIdlerWrapper > s_IdlerWrapper
Definition: ncbiapp.cpp:1837
#define NCBI_LOG_PARAM(type, Name, NAME)
Definition: ncbiapp.cpp:472
const char * s_ArgFullVersionXml
Definition: ncbiargs.cpp:86
const char * s_ArgFullVersionJson
Definition: ncbiargs.cpp:87
NCBI_PARAM_DEF_EX(bool, Debug, Catch_Unhandled_Exceptions, true, eParam_NoThread, DEBUG_CATCH_UNHANDLED_EXCEPTIONS)
static CSafeStatic< CRWLock > s_InstanceRWLock(CSafeStaticLifeSpan(CSafeStaticLifeSpan::eLifeSpan_Long, 1))
ELogOptionsEvent
Definition: ncbiapp.cpp:487
@ eStartEvent
right before AppMain()
Definition: ncbiapp.cpp:488
@ eOtherEvent
any case is fine
Definition: ncbiapp.cpp:490
@ eStopEvent
right after AppMain()
Definition: ncbiapp.cpp:489
const char * s_ArgFullVersion
Definition: ncbiargs.cpp:85
typedef NCBI_PARAM_TYPE(Debug, Catch_Unhandled_Exceptions) TParamCatchExceptions
#define RES_SIZE_USAGE(name, value_in_bytes)
Definition: ncbiapp.cpp:548
bool s_HandleExceptions(void)
Definition: ncbiapp.cpp:402
const char * s_ArgLogFile
Definition: ncbiargs.cpp:82
const char * s_ArgCfgFile
Definition: ncbiargs.cpp:83
DEFINE_STATIC_MUTEX(s_InstanceMutex)
NCBI_PARAM_DECL(bool, Debug, Catch_Unhandled_Exceptions)
ELogOptions
Flags to switch what to log.
Definition: ncbiapp.cpp:495
@ fLogAppRegistryStop
log app registry on app stop
Definition: ncbiapp.cpp:499
@ fLogAppPath
log app executable path
Definition: ncbiapp.cpp:501
@ fLogAppResUsageStop
log resource usage on app stop
Definition: ncbiapp.cpp:502
@ fLogAppArguments
log app arguments
Definition: ncbiapp.cpp:500
@ fLogAppEnvironment
log app environment on app start
Definition: ncbiapp.cpp:496
@ fLogAppRegistry
log app registry on app start
Definition: ncbiapp.cpp:498
@ fLogAppEnvironmentStop
log app environment on app stop
Definition: ncbiapp.cpp:497
static bool s_IsApplicationStarted
Definition: ncbiapp.cpp:89
#define RES_TIME_USAGE(name, value)
Definition: ncbiapp.cpp:556
void s_RoundResUsageSize(Uint8 value_in_bytes, string &suffix, Uint8 &value)
Definition: ncbiapp.cpp:533
const char * s_ArgDryRun
Definition: ncbiargs.cpp:88
const char * s_ArgVersion
Definition: ncbiargs.cpp:84
const char * s_ArgDelimiter
Definition: ncbiargs.cpp:89
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
#define NCBI_OS_UNIX
Define class Dll and for Portable DLL handling.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
@ eSecond
Definition: ncbitime.cpp:2758
T max(T x_, T y_)
std::istream & in(std::istream &in_, double &x_)
#define BOOL
Definition: odbcinst.h:18
static const char * suffix[]
Definition: pcregrep.c:408
Defines CRequestContext class for NCBI C++ diagnostic API.
DWORD * LPDWORD
Definition: sqltypes.h:113
unsigned int DWORD
Definition: sqltypes.h:98
#define NcbiSys_getenv
Definition: ncbisys.hpp:90
#define NcbiSys_setmode
Definition: ncbisys.hpp:47
#define NcbiSys_fileno
Definition: ncbisys.hpp:43
NCBI
Definition: static_set.hpp:72
CCompressionStreamProcessor * s_Init(EInitType type, CCompressStream::EMethod method, ICompression::TFlags flags, ICompression::ELevel level)
CRef< IRWRegistry > registry
Definition: metareg.hpp:78
string actual_name
Either an absolute path or empty.
Definition: metareg.hpp:75
Process memory usage information, in bytes.
This class allows to add build info (date and tag) to application version.
Definition: version_api.hpp:62
Definition: inftrees.h:24
Portable system-logging API.
#define _ASSERT
Modified on Tue Apr 16 20:13:49 2024 by modify_doxy.py rev. 669887