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

Go to the SVN repository for this file.

1 /* $Id: ncbiapp.cpp 102773 2024-07-10 13:26:23Z grichenk $
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) {
714  if (cur_ctx != e_ctx) {
717  "CException thrown", e);
718  auto e_span = e_ctx->GetTracerSpan();
719  if ( e_span ) {
720  e_span->SetSpanStatus(ITracerSpan::eError);
721  e_span->EndSpan();
722  }
724  }
726  "Application's execution failed", e);
727  *got_exception = true;
728  *exit_code = 3;
729  }
730  catch (const exception& e) {
731  ERR_POST_X(7, "Application's execution failed: " << e.what());
732  *got_exception = true;
733  *exit_code = 3;
734  }
735  }
736  else {
737  *exit_code = m_DryRun ? DryRun() : Run();
738  }
739  }
741  if ( span ) {
742  if (*exit_code != 0 || *got_exception) {
743  span->SetSpanStatus(ITracerSpan::eError);
744  }
745  span->EndSpan();
746  }
749 
750  // Close application
751  if ( s_HandleExceptions() ) {
752  try {
753  Exit();
754  }
755  catch (CArgException& e) {
756  NCBI_RETHROW_SAME(e, "Application's cleanup failed");
757  }
758  catch (const CException& e) {
759  NCBI_REPORT_EXCEPTION_X(17, "Application's cleanup failed", e);
760  *got_exception = true;
761  }
762  catch (const exception& e) {
763  ERR_POST_X(8, "Application's cleanup failed: "<< e.what());
764  *got_exception = true;
765  }
766  }
767  else {
768  Exit();
769  }
770 }
771 
772 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
773 static
774 void s_Create_ArgsOrEnvW(
775  vector<string>& storage,
776  AutoArray<const char*>& pointers,
777  const TXChar* const* begin)
778 {
779  const TXChar* const* arg = begin;
780  size_t count = 0;
781  while( *(arg++) )
782  ++count;
783 
784  const char** args = new const char*[count+1];
785  if ( !args ) {
786  NCBI_THROW(CCoreException, eNullPtr, kEmptyStr);
787  }
788  pointers = args;
789 
790  arg = begin;
791  size_t i=0;
792  for (i=0; i<count; ++i) {
793  storage.push_back( _T_STDSTRING( *(arg++) ) );
794  }
795 
796  for (i=0; i < storage.size(); ++i) {
797  args[i] = storage[i].c_str();
798  }
799  args[i] = NULL;
800 }
801 
803 (int argc,
804  const TXChar* const* argv,
805  const TXChar* const* envp,
806  EAppDiagStream diag,
807  const TXChar* conf,
808  const TXString& name)
809 {
810  vector< string> argv_storage;
811  AutoArray<const char*> argv_pointers;
812  if (argv) {
813  s_Create_ArgsOrEnvW(argv_storage, argv_pointers, argv);
814  }
815 
816  vector< string> envp_storage;
817  AutoArray<const char*> envp_pointers;
818  if (envp) {
819  s_Create_ArgsOrEnvW(envp_storage, envp_pointers, envp);
820  }
821 
822  return AppMain(argc,
823  argv == NULL ? NULL : argv_pointers.get(),
824  envp == NULL ? NULL : envp_pointers.get(),
825  diag,
826  conf == NULL ? NULL : (conf == NcbiEmptyXCStr ? NcbiEmptyCStr : _T_CSTRING(conf)),
827  name == NcbiEmptyXString ? NcbiEmptyString : _T_STDSTRING(name));
828 }
829 #endif
830 
832 (int argc,
833  const char* const* argv,
834  const char* const* envp,
835  EAppDiagStream diag,
836  const char* conf,
837  const string& name)
838 {
839  if (conf) {
840  m_DefaultConfig = conf;
841  }
842  x_SetupStdio();
843 
844  // Check if logfile is set in the args.
845  m_LogFile = 0;
846  if (!m_DisableArgDesc && argc > 1 && argv && diag != eDS_User) {
847  for (int i = 1; i < argc; i++) {
848  if ( !argv[i] ) {
849  continue;
850  }
851  if ( NStr::strcmp(argv[i], s_ArgDelimiter) == 0 ) {
852  break;
853  }
854  if ( NStr::strcmp(argv[i], s_ArgLogFile) == 0 ) {
855  if (!argv[++i]) {
856  continue;
857  }
858  m_LogFile = argv[i];
859  } else if (NStr::StartsWith(argv[i], s_ArgLogFile)) {
860  const char *a = argv[i] + strlen(s_ArgLogFile);
861  if (*a == '=') {
862  m_LogFile = ++a;
863  }
864  }
865  }
866  }
867 
868  // Setup logging as soon as possible.
869  // Setup for diagnostics
870  try {
872  } catch (const CException& e) {
873  NCBI_RETHROW(e, CAppException, eSetupDiag,
874  "Application diagnostic stream's setup failed");
875  } catch (const exception& e) {
876  NCBI_THROW(CAppException, eSetupDiag,
877  "Application diagnostic stream's setup failed: " +
878  string(e.what()));
879  }
880 
881  // Get program executable's name & path.
882  string exepath = FindProgramExecutablePath(argc, argv, &m_RealExePath);
883  m_ExePath = exepath;
884 
885  // Get program display name
886  string appname = name;
887  if (appname.empty()) {
888  if (!exepath.empty()) {
889  CDirEntry::SplitPath(exepath, NULL, &appname);
890  } else if (argc > 0 && argv && argv[0] != NULL && *argv[0] != '\0') {
891  CDirEntry::SplitPath(argv[0], NULL, &appname);
892  } else {
893  appname = "ncbi";
894  }
895  }
896  if ( m_ProgramDisplayName.empty() ) {
897  SetProgramDisplayName(appname);
898  }
899 
900  // Make sure we have something as our 'real' executable's name.
901  // though if it does not contain a full path it won't be much use.
902  if ( exepath.empty() ) {
904  << "Warning: Could not determine this application's "
905  "file name and location. Using \""
906  << appname << "\" instead.\n"
907  "Please fix FindProgramExecutablePath() on this platform.");
908  exepath = appname;
909  }
910 
911 #if defined(NCBI_OS_DARWIN)
912  // We do not know standard way of passing arguments to C++ program on Mac,
913  // so we will read arguments from special file having extension ".args"
914  // and name equal to display name of program (name argument of AppMain).
915  s_MacArgMunging(*this, &argc, &argv, exepath);
916 #endif
917 
918  CDiagContext& diag_context = GetDiagContext();
919 
920  // Preparse command line
921  if (PreparseArgs(argc, argv) == ePreparse_Exit) {
922  diag_context.DiscardMessages();
923  return 0;
924  }
925 
926  // Check command line for presence special arguments
927  // "-logfile", "-conffile", "-version"
928  const char* conf_arg = nullptr;
929  if (!m_DisableArgDesc && argc > 1 && argv) {
930  const char** v = new const char*[argc];
931  v[0] = argv[0];
932  int real_arg_index = 1;
933  bool skip = false;
934  for (int i = 1; i < argc; i++) {
935  if ( !argv[i] ) {
936  continue;
937  }
938  if ( NStr::strcmp(argv[i], s_ArgDelimiter) == 0 ) {
939  skip = true;
940  }
941  if (skip) {
942  v[real_arg_index++] = argv[i];
943  continue;
944  }
945  // Log file - ignore if diag is eDS_User - the user wants to
946  // take care about logging.
947  if ( diag != eDS_User &&
948  NStr::strcmp(argv[i], s_ArgLogFile) == 0 ) {
949  if (!argv[++i]) {
950  continue;
951  }
952  v[real_arg_index++] = argv[i - 1];
953  v[real_arg_index++] = argv[i];
954  // Configuration file
955  } else if ( NStr::strcmp(argv[i], s_ArgCfgFile) == 0 ) {
956  if (!argv[++i]) {
957  continue;
958  }
959  v[real_arg_index++] = argv[i - 1];
960  v[real_arg_index++] = argv[i];
961  conf_arg = argv[i];
962 
963  }
964  else if (NStr::StartsWith(argv[i], s_ArgCfgFile)) {
965  v[real_arg_index++] = argv[i];
966  const char* a = argv[i] + strlen(s_ArgCfgFile);
967  if (*a == '=') {
968  conf_arg = ++a;
969  }
970 
971  // Version
972  } else if ( NStr::strcmp(argv[i], s_ArgVersion) == 0 ) {
973  delete[] v;
974  // Print VERSION
976  diag_context.DiscardMessages();
977  return 0;
978 
979  // Full version
980  } else if ( NStr::strcmp(argv[i], s_ArgFullVersion) == 0 ) {
981  delete[] v;
982  // Print full VERSION
983  cout << GetFullVersion().Print( appname );
984  diag_context.DiscardMessages();
985  return 0;
986  } else if ( NStr::strcmp(argv[i], s_ArgFullVersionXml) == 0 ) {
987  delete[] v;
988  // Print full VERSION in XML format
989  cout << GetFullVersion().PrintXml( appname );
990  diag_context.DiscardMessages();
991  return 0;
992  } else if ( NStr::strcmp(argv[i], s_ArgFullVersionJson) == 0 ) {
993  delete[] v;
994  // Print full VERSION in JSON format
995  cout << GetFullVersion().PrintJson( appname );
996  diag_context.DiscardMessages();
997  return 0;
998 
999  // Dry run
1000  } else if ( NStr::strcmp(argv[i], s_ArgDryRun) == 0 ) {
1001  m_DryRun = true;
1002 
1003  // Save real argument
1004  } else {
1005  v[real_arg_index++] = argv[i];
1006  }
1007  }
1008  if (real_arg_index == argc ) {
1009  delete[] v;
1010  } else {
1011  argc = real_arg_index;
1012  argv = v;
1013  }
1014  if (conf_arg) {
1015  if (CFile(conf_arg).Exists()) {
1016  conf = conf_arg;
1017  }
1018  else {
1019  ERR_POST_X(23, Critical << "Registry file \"" << conf_arg << "\" not found, aborting.");
1020  Abort();
1021  }
1022  }
1023  }
1024 
1025  // Reset command-line args and application name
1026  m_Arguments->Reset(argc, argv, exepath, m_RealExePath);
1027 
1028  // Reset application environment
1029  m_Environ->Reset(envp);
1030 
1031  // Setup some debugging features from environment variables.
1032  if ( !m_Environ->Get(DIAG_TRACE).empty() ) {
1034  }
1035  string post_level = m_Environ->Get(DIAG_POST_LEVEL);
1036  if ( !post_level.empty() ) {
1037  EDiagSev sev;
1038  if (CNcbiDiag::StrToSeverityLevel(post_level.c_str(), sev)) {
1039  SetDiagFixedPostLevel(sev);
1040  }
1041  }
1042  if ( !m_Environ->Get(ABORT_ON_THROW).empty() ) {
1043  SetThrowTraceAbort(true);
1044  }
1045 
1046  // Clear registry content
1047  m_Config->Clear();
1048 
1049  // Call: Init() + Run() + Exit()
1050  int exit_code = 1;
1051  bool got_exception = false;
1052  s_IsApplicationStarted = true;
1053 
1054  try {
1055  if ( s_HandleExceptions() ) {
1056  try {
1057  x_TryMain(diag, conf, &exit_code, &got_exception);
1058  }
1059  catch (const CArgException&) {
1060  // This exceptions will be caught later regardless of the
1061  // handle-exceptions flag.
1062  throw;
1063  }
1064 #if defined(NCBI_COMPILER_MSVC) && defined(_DEBUG)
1065  // Microsoft promotes many common application errors to exceptions.
1066  // This includes occurrences such as dereference of a NULL pointer and
1067  // walking off of a dangling pointer. The catch-all is lifted only in
1068  // debug mode to permit easy inspection of such error conditions, while
1069  // maintaining safety of production, release-mode applications.
1070  catch (...) {
1071  ERR_POST_X(10, Warning <<
1072  "Application has thrown an exception of unknown type");
1073  throw;
1074  }
1075 #endif
1076  }
1077  else {
1078 #ifdef NCBI_OS_MSWIN
1079  if ( !IsDebuggerPresent() ) {
1081  }
1082 #endif
1083  x_TryMain(diag, conf, &exit_code, &got_exception);
1084  }
1085  }
1086  catch (const CArgException& e) {
1087  // Print USAGE and the exception error message
1088  if ( e.GetErrCode() != CArgException::eNoValue && m_ArgDesc.get() ) {
1089  x_AddDefaultArgs();
1090  string str;
1091  if ( !m_ArgDesc->IsSetMiscFlag(CArgDescriptions::fNoUsage) ) {
1092  m_ArgDesc->PrintUsage(str);
1093  cerr << str;
1094  }
1095  if ( !m_ArgDesc->IsSetMiscFlag(CArgDescriptions::fDupErrToCerr) ) {
1096  CStreamDiagHandler* errh =
1097  dynamic_cast<CStreamDiagHandler*>(GetDiagHandler());
1098  if (!errh || errh->GetStream() != &cerr) {
1099  cerr << "Error in command-line arguments. "
1100  "See error logs for more details." << endl;
1101  }
1102  }
1103  else {
1104  cerr << "Error in command-line arguments." << endl;
1105  cerr << e.what() << endl;
1106  }
1107  cerr << string(72, '=') << endl << endl;
1108  }
1110  NCBI_REPORT_EXCEPTION_X(18, "", e);
1111  got_exception = true;
1112  exit_code = 1;
1113  }
1114 
1115  if (!diag_context.IsSetExitCode()) {
1116  diag_context.SetExitCode(exit_code);
1117  }
1118 
1119  if (m_ExitCodeCond == eAllExits
1120  || (got_exception && m_ExitCodeCond == eExceptionalExits)) {
1121  _TRACE("Overriding exit code from " << exit_code
1122  << " to " << m_ExitCode);
1123  exit_code = m_ExitCode;
1124  }
1125 
1126  // Application stop
1127  AppStop(exit_code);
1128 
1129  if ((m_AppFlags & fSkipSafeStaticDestroy) == 0) {
1130  // Destroy short-lived statics
1132  }
1133 
1134  // Exit
1135  return exit_code;
1136 }
1137 
1138 
1139 void CNcbiApplicationAPI::SetEnvironment(const string& name, const string& value)
1140 {
1141  SetEnvironment().Set(name, value);
1142 }
1143 
1144 #if 0
1146 {
1148 }
1149 
1150 void CNcbiApplicationAPI::SetVersion(int major, int minor)
1151 {
1153 }
1154 
1155 void CNcbiApplicationAPI::SetVersion(int major, int minor, int patch)
1156 {
1157  m_Version->SetVersionInfo(major, minor, patch,
1159 }
1160 #else
1162 {
1164 }
1165 #endif
1166 
1167 
1169 {
1170  if ( s_IsApplicationStarted ) {
1171  ERR_POST_X(19, "SetVersion() should be used from constructor of " \
1172  "CNcbiApplication derived class, see description");
1173  }
1175 }
1176 
1178  const SBuildInfo& build_info)
1179 {
1180  if ( s_IsApplicationStarted ) {
1181  ERR_POST_X(19, "SetVersion() should be used from constructor of " \
1182  "CNcbiApplication derived class, see description");
1183  }
1184  m_Version->SetVersionInfo(new CVersionInfo(version), build_info);
1185 }
1186 
1188 {
1189  if ( s_IsApplicationStarted ) {
1190  ERR_POST_X(19, "SetFullVersion() should be used from constructor of "\
1191  "CNcbiApplication derived class, see description");
1192  }
1193  m_Version.Reset( version );
1194 }
1195 
1196 
1198 {
1199  return m_Version->GetVersionInfo();
1200 }
1201 
1203 {
1204  return *m_Version;
1205 }
1206 
1207 
1209 {
1210  m_ArgDesc.reset(arg_desc);
1211 
1212  if ( arg_desc ) {
1213  if ( !m_DisableArgDesc ) {
1214  for(CArgDescriptions* desc : m_ArgDesc->GetAllDescriptions()) {
1215  desc->AddDefaultFileArguments(m_DefaultConfig);
1216  }
1217  }
1218  m_Args.reset(arg_desc->CreateArgs(GetArguments()));
1219  } else {
1220  m_Args.reset();
1221  }
1222 }
1223 
1224 
1226 {
1228  return true;
1229 }
1230 
1231 
1233 {
1235  return true;
1236 }
1237 
1238 
1240  const string* conf,
1241  CNcbiRegistry::TFlags reg_flags)
1242 {
1243  string basename (m_Arguments->GetProgramBasename(eIgnoreLinks));
1244  string basename2(m_Arguments->GetProgramBasename(eFollowLinks));
1245  CMetaRegistry::SEntry entry;
1246 
1247  if ( !conf ) {
1248  if (reg.IncludeNcbircIfAllowed(reg_flags)) {
1250  ("ncbi", CMetaRegistry::eName_RcOrIni);
1251  }
1252  m_ConfigLoaded = true;
1253  return false;
1254  } else if (conf->empty()) {
1256  reg_flags, &reg);
1257  if ( !entry.registry && basename2 != basename ) {
1258  entry = CMetaRegistry::Load(basename2, CMetaRegistry::eName_Ini, 0,
1259  reg_flags, &reg);
1260  }
1262  } else {
1264  reg_flags, &reg);
1265  }
1266  if ( !entry.registry ) {
1267  // failed; complain as appropriate
1268  string dir;
1269  CDirEntry::SplitPath(*conf, &dir, 0, 0);
1270  if (dir.empty()) {
1271  ERR_POST_X(11, Info <<
1272  "Registry file of application \"" << basename
1273  << "\" is not found");
1274  } else {
1275  NCBI_THROW(CAppException, eNoRegistry,
1276  "Registry file \"" + *conf + "\" cannot be opened");
1277  }
1278  // still consider pulling in defaults from .ncbirc
1279  if (reg.IncludeNcbircIfAllowed(reg_flags)) {
1281  ("ncbi", CMetaRegistry::eName_RcOrIni);
1282  }
1283  m_ConfigLoaded = true;
1284  return false;
1285  } else if (entry.registry != static_cast<IRWRegistry*>(&reg)) {
1286  // should be impossible with new CMetaRegistry interface...
1287  if (&reg == m_Config && reg.Empty()) {
1288  m_Config.Reset(dynamic_cast<CNcbiRegistry*>
1289  (entry.registry.GetPointer()));
1290  } else {
1291  // copy into reg
1293  entry.registry->Write(str);
1294  str.seekg(0);
1295  reg.Read(str);
1296  }
1297  }
1298  m_ConfigPath = entry.actual_name;
1299  m_ConfigLoaded = true;
1300  return true;
1301 }
1302 
1303 
1305  const string* conf)
1306 {
1307  return LoadConfig(reg, conf, IRegistry::fWithNcbirc);
1308 }
1309 
1310 
1313  const char* const* /*argv*/)
1314 {
1315  return ePreparse_Continue;
1316 }
1317 
1318 
1320 {
1321  m_DisableArgDesc = disable;
1322 }
1323 
1324 
1326 {
1327  m_HideArgs = hide_mask;
1328 }
1329 
1330 
1332 {
1333  // do not call this function more than once
1334  // and from places other than App constructor
1335  _ASSERT(m_StdioFlags == 0);
1336  m_StdioFlags = stdio_flags;
1337 }
1338 
1339 
1341 {
1342  if ((m_StdioFlags & fNoSyncWithStdio) != 0) {
1343  IOS_BASE::sync_with_stdio(false);
1344  }
1345 
1347 #ifdef NCBI_OS_UNIX
1348  && !isatty(0)
1349 #endif
1350  ) {
1351 #if defined(NCBI_COMPILER_GCC) && defined(NCBI_OS_SOLARIS)
1352  _ASSERT(!m_CinBuffer);
1353  // Ugly workaround for ugly interaction between g++ and Solaris C RTL
1354  const size_t kCinBufSize = 5120;
1355  m_CinBuffer = new char[kCinBufSize];
1356  cin.rdbuf()->pubsetbuf(m_CinBuffer, kCinBufSize);
1357 #endif
1358  }
1359 #ifdef NCBI_OS_MSWIN
1360  if ((m_StdioFlags & fBinaryCin) != 0) {
1361  NcbiSys_setmode(NcbiSys_fileno(stdin), O_BINARY);
1362  }
1363  if ((m_StdioFlags & fBinaryCout) != 0) {
1364  NcbiSys_setmode(NcbiSys_fileno(stdout), O_BINARY);
1365  }
1366 #endif
1367 }
1368 
1370 {
1372  for(CArgDescriptions* desc : m_ArgDesc->GetAllDescriptions())
1373  {
1374  desc->AddStdArguments(mask);
1376  }
1377 }
1378 
1380 {
1381  if (app_name.empty()) return;
1382  m_ProgramDisplayName = app_name;
1383  // Also set app_name in the diag context
1384  if ( GetDiagContext().GetAppName().empty() ) {
1385  GetDiagContext().SetAppName(app_name);
1386  }
1387 }
1388 
1389 
1390 string CNcbiApplicationAPI::GetAppName(EAppNameType name_type, int argc, const char* const* argv)
1391 {
1392  CNcbiApplicationGuard instance = InstanceGuard();
1393  string app_name;
1394 
1395  switch (name_type) {
1396  case eBaseName:
1397  if (instance) {
1398  app_name = instance->GetProgramDisplayName();
1399  } else {
1400  string exe_path = FindProgramExecutablePath(argc, argv);
1401  CDirEntry::SplitPath(exe_path, NULL, &app_name);
1402  }
1403  break;
1404 
1405  case eFullName:
1406  if (instance) {
1407  app_name = instance->GetProgramExecutablePath(eIgnoreLinks);
1408  } else {
1409  app_name = FindProgramExecutablePath(argc, argv);
1410  }
1411  break;
1412 
1413  case eRealName:
1414  if (instance) {
1415  app_name = instance->GetProgramExecutablePath(eFollowLinks);
1416  } else {
1417  FindProgramExecutablePath(argc, argv, &app_name);
1418  }
1419  break;
1420  }
1421 
1422  return app_name;
1423 }
1424 
1425 
1427  int argc,
1428  const char* const* argv,
1429  string* real_path
1430 )
1431 {
1432  // Cache program executable path, it doesn't change during execution
1433 
1434  static CSafeStatic<string> s_Path;
1435  static CSafeStatic<string> s_RealPath;
1436  static bool s_Init = false;
1437 
1438  if (s_Init) {
1439  // Return cached value
1440  if (real_path) {
1441  *real_path = *s_RealPath;
1442  }
1443  return *s_Path;
1444  }
1445  s_Init = true;
1446 
1447  CNcbiApplicationGuard instance = InstanceGuard();
1448  string ret_val;
1449 
1450  _ASSERT(argc >= 0); // formally signed for historical reasons
1451  _ASSERT(argv != NULL || argc == 0);
1452  if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0') {
1453  ret_val = argv[0];
1454  } else if (instance) {
1455  ret_val = instance->GetArguments().GetProgramName();
1456  }
1457 
1458 #if defined(NCBI_OS_MSWIN) || defined(NCBI_OS_UNIX)
1459 
1460 # ifdef NCBI_OS_MSWIN
1461 
1462  // MS Windows: Try more accurate method of detection.
1463  try {
1464  // Load PSAPI dynamic library -- it should exist on MS-Win NT/2000/XP
1465  CDll dll_psapi("psapi.dll", CDll::eLoadNow, CDll::eAutoUnload);
1466 
1467  // Get function entry-point from DLL
1468  BOOL (STDMETHODCALLTYPE FAR * dllEnumProcessModules)
1469  (HANDLE hProcess, // handle to process
1470  HMODULE *lphModule, // array of module handles
1471  DWORD cb, // size of array
1472  LPDWORD lpcbNeeded // number of bytes required
1473  ) = NULL;
1474 
1475  dllEnumProcessModules = dll_psapi.GetEntryPoint_Func("EnumProcessModules", &dllEnumProcessModules);
1476  if ( !dllEnumProcessModules ) {
1478  }
1479 
1480  // Find executable file in the midst of all loaded modules
1481  HANDLE process = GetCurrentProcess();
1482  HMODULE module = 0;
1483  DWORD needed = 0;
1484 
1485  // Get first module of current process (it should be .exe file)
1486  if ( dllEnumProcessModules(process, &module, sizeof(HMODULE), &needed) ) {
1487  if ( needed && module ) {
1488  TXChar buf[MAX_PATH + 1];
1489  DWORD ncount = GetModuleFileName(module, buf, MAX_PATH);
1490  if (ncount > 0) {
1491  // Save to cache and return
1492  *s_Path = _T_STDSTRING(buf);
1493  *s_RealPath = CDirEntry::NormalizePath(*s_Path, eFollowLinks);
1494  if (real_path) {
1495  *real_path = *s_RealPath;
1496  }
1497  return *s_Path;
1498  }
1499  }
1500  }
1501  }
1502  catch (const CException&) {
1503  ; // Just catch an all exceptions from CDll
1504  }
1505  // This method didn't work -- use standard method
1506 # endif
1507 
1508 # ifdef NCBI_OS_LINUX
1509  // Linux OS: Try more accurate method of detection for real_path
1510  if (ret_val.empty() && !real_path) {
1511  real_path = &ret_val;
1512  }
1513  if (real_path) {
1514  char buf[PATH_MAX + 1];
1515  string procfile = "/proc/" + NStr::IntToString(getpid()) + "/exe";
1516  int ncount = (int)readlink((procfile).c_str(), buf, PATH_MAX);
1517  if (ncount > 0) {
1518  real_path->assign(buf, ncount);
1519  if (real_path == &ret_val || ret_val.empty()) {
1520  // Save to cache and return
1521  *s_Path = *real_path;
1522  *s_RealPath = *real_path;
1523  return *real_path;
1524  }
1525  real_path = 0;
1526  }
1527  }
1528 # endif
1529 
1530  if (ret_val.empty()) {
1531  // nothing to go on :-/
1532  // don't need to update cached values, they are empty
1533  if (real_path) {
1534  real_path->erase();
1535  }
1536  // This can happens on non-Windows/Linux platforms if logging is used
1537  // before CNcbiApplication initialization, and no argc/argv valuies passed in arguments.
1538  // As a fallback reset the initialization state, so it can be (maybe) initialized correctly later.
1539 #if !defined(NCBI_OS_MSWIN) && !defined(NCBI_OS_LINUX)
1540  if (argc == 0) {
1541  s_Init = false;
1542  }
1543 #endif
1544  return kEmptyStr;
1545  }
1546 
1547  // Default approach (using value from arguments):
1548 
1549  string app_path = ret_val;
1550 
1551  if ( !CDirEntry::IsAbsolutePath(app_path) ) {
1552 # ifdef NCBI_OS_MSWIN
1553  // Add default ".exe" extention to the name of executable file
1554  // if it running without extension
1555  string dir, title, ext;
1556  CDirEntry::SplitPath(app_path, &dir, &title, &ext);
1557  if ( ext.empty() ) {
1558  app_path = CDirEntry::MakePath(dir, title, "exe");
1559  }
1560 # endif
1561  if ( CFile(app_path).Exists() ) {
1562  // Relative path from the the current directory
1563  app_path = CDir::GetCwd() + CDirEntry::GetPathSeparator() + app_path;
1564  if ( !CFile(app_path).Exists() ) {
1565  app_path = kEmptyStr;
1566  }
1567  } else {
1568  // Running from some path from PATH environment variable.
1569  // Try to determine that path.
1570  string env_path;
1571  if (instance) {
1572  env_path = instance->GetEnvironment().Get("PATH");
1573  } else {
1574  env_path = _T_STDSTRING(NcbiSys_getenv(_TX("PATH")));
1575  }
1576  list<string> split_path;
1577 # ifdef NCBI_OS_MSWIN
1578  NStr::Split(env_path, ";", split_path,
1580 # else
1581  NStr::Split(env_path, ":", split_path,
1583 # endif
1584  string base_name = CDirEntry(app_path).GetBase();
1585  ITERATE(list<string>, it, split_path) {
1586  app_path = CDirEntry::MakePath(*it, base_name);
1587  if ( CFile(app_path).Exists() ) {
1588  break;
1589  }
1590  app_path = kEmptyStr;
1591  }
1592  }
1593  }
1594  ret_val = CDirEntry::NormalizePath(
1595  (app_path.empty() && argv != NULL && argv[0] != NULL) ? argv[0] : app_path);
1596 
1597 #else // defined (NCBI_OS_MSWIN) || defined(NCBI_OS_UNIX)
1598 
1599 # error "Unsupported platform, sorry -- please contact NCBI"
1600 
1601 #endif
1602 
1603  // Save to cache and return
1604  *s_Path = ret_val;
1605  *s_RealPath = CDirEntry::NormalizePath(ret_val, eFollowLinks);
1606  if (real_path) {
1607  *real_path = *s_RealPath;
1608  }
1609  return *s_Path;
1610 }
1611 
1612 
1614 {
1615  if (reg == 0) {
1616  reg = m_Config.GetPointer();
1617  if (reg == 0)
1618  return;
1619  }
1620 
1622 
1623  // [NCBI.MEMORY_FILL]
1624  CObject::SetAllocFillMode(reg->Get("NCBI", "MEMORY_FILL"));
1625 
1626  {{
1627  CSysLog* syslog = dynamic_cast<CSysLog*>(GetDiagHandler());
1628  if (syslog) {
1629  syslog->HonorRegistrySettings(reg);
1630  }
1631  }}
1632 
1633  // Debugging features
1634 
1635  // [DEBUG.DIAG_TRACE]
1636  if ( !reg->Get("DEBUG", DIAG_TRACE).empty() ) {
1638  }
1639 
1640  // [DEBUG.ABORT_ON_THROW]
1641  if ( !reg->Get("DEBUG", ABORT_ON_THROW).empty() ) {
1642  SetThrowTraceAbort(true);
1643  }
1644 
1645  // [DEBUG.DIAG_POST_LEVEL]
1646  string post_level = reg->Get("DEBUG", DIAG_POST_LEVEL);
1647  if ( !post_level.empty() ) {
1648  EDiagSev sev;
1649  if (CNcbiDiag::StrToSeverityLevel(post_level.c_str(), sev)) {
1650  SetDiagFixedPostLevel(sev);
1651  }
1652  }
1653 
1654  // [DEBUG.MessageFile]
1655  string msg_file = reg->Get("DEBUG", DIAG_MESSAGE_FILE);
1656  if ( !msg_file.empty() ) {
1658  if ( !info || !info->Read(msg_file) ) {
1659  if ( info ) {
1660  delete info;
1661  }
1662  ERR_POST_X(12, Warning << "Applications message file \""
1663  << msg_file
1664  << "\" is not found");
1665  } else {
1667  }
1668  }
1669 
1670  // [DEBUG.GuardAgainstThreadsOnStaticDataDestruction]
1671  if ( !reg->GetBool("DEBUG", "GuardAgainstThreadsOnStaticDataDestruction", true, 0, IRegistry::eErrPost) ) {
1673  }
1674 
1675  // CPU and memory limitations
1676 
1677  // [NCBI.HeapSizeLimit]
1678  if ( !reg->Get("NCBI", "HeapSizeLimit").empty() ) {
1679  ERR_POST_X(13, Warning
1680  << "Config param [NCBI.HeapSizeLimit] is deprecated,"
1681  << "please use [NCBI.MemorySizeLimit] instead.");
1682  int mem_size_limit = reg->GetInt("NCBI", "HeapSizeLimit", 0);
1683  if (mem_size_limit < 0) {
1684  NCBI_THROW(CAppException, eLoadConfig,
1685  "Configuration file error: [NCBI.HeapSizeLimit] < 0");
1686  }
1687  SetMemoryLimit(size_t(mem_size_limit) * 1024 * 1024);
1688  }
1689  // [NCBI.MemorySizeLimit]
1690  if ( !reg->Get("NCBI", "MemorySizeLimit").empty() ) {
1691  size_t mem_size_limit = 0;
1692  string s = reg->GetString("NCBI", "MemorySizeLimit", kEmptyStr);
1693  size_t pos = s.find("%");
1694  if (pos != NPOS) {
1695  // Size in percents of total memory
1696  size_t percents = NStr::StringToUInt(CTempString(s, 0, pos));
1697  if (percents > 100) {
1698  NCBI_THROW(CAppException, eLoadConfig,
1699  "Configuration file error: [NCBI.HeapSizeLimit] > 100%");
1700  }
1701  mem_size_limit = (size_t)(CSystemInfo::GetTotalPhysicalMemorySize() * percents / 100);
1702  } else {
1703  try {
1704  // Size is specified in MiB by default if no suffixes
1705  // (converted without exception)
1706  mem_size_limit = NStr::StringToSizet(s) * 1024 * 1024;
1707  }
1708  catch (const CStringException&) {
1709  // Otherwise, size have suffix (MiB, G, GB, etc)
1711  if ( bytes > get_limits(mem_size_limit).max() ) {
1712  NCBI_THROW(CAppException, eLoadConfig,
1713  "Configuration file error: [NCBI.MemorySizeLimit] is too big");
1714  }
1715  mem_size_limit = (size_t)bytes;
1716  }
1717  }
1718  SetMemoryLimit(mem_size_limit);
1719  }
1720 
1721  // [NCBI.CpuTimeLimit]
1722  if ( !reg->Get("NCBI", "CpuTimeLimit").empty() ) {
1723  int cpu_time_limit = reg->GetInt("NCBI", "CpuTimeLimit", 0);
1724  if (cpu_time_limit < 0) {
1725  NCBI_THROW(CAppException, eLoadConfig,
1726  "Configuration file error: [NCBI.CpuTimeLimit] < 0");
1727  }
1728  SetCpuTimeLimit((unsigned int)cpu_time_limit, 5, NULL, NULL);
1729  }
1730 
1731  // TRACE and POST filters
1732 
1733  try {
1734  // [DIAG.TRACE_FILTER]
1735  string trace_filter = reg->Get("DIAG", "TRACE_FILTER");
1736  if ( !trace_filter.empty() )
1737  SetDiagFilter(eDiagFilter_Trace, trace_filter.c_str());
1738  } NCBI_CATCH_X(20,
1739  "Failed to load and set diag. filter for traces");
1740 
1741  try {
1742  // [DIAG.POST_FILTER]
1743  string post_filter = reg->Get("DIAG", "POST_FILTER");
1744  if ( !post_filter.empty() )
1745  SetDiagFilter(eDiagFilter_Post, post_filter.c_str());
1746  } NCBI_CATCH_X(21,
1747  "Failed to load and set diag. filter for regular errors");
1748 }
1749 
1750 
1752 {
1753  string cmd_line = GetProgramExecutablePath();
1754  if ( m_Arguments.get() ) {
1755  if ( cmd_line.empty() ) {
1756  cmd_line = (*m_Arguments)[0];
1757  }
1758  for (SIZE_TYPE arg = 1; arg < m_Arguments->Size(); ++arg) {
1759  cmd_line += " ";
1760  cmd_line += NStr::ShellEncode((*m_Arguments)[arg]);
1761  }
1762  }
1763 
1764  // Print application start message
1766  GetDiagContext().PrintStart(cmd_line);
1767  }
1768 }
1769 
1770 
1771 void CNcbiApplicationAPI::AppStop(int exit_code)
1772 {
1774  if ( !ctx.IsSetExitCode() ) {
1775  ctx.SetExitCode(exit_code);
1776  }
1777 }
1778 
1779 
1781 {
1782  m_ExitCode = exit_code;
1783  m_ExitCodeCond = when;
1784 }
1785 
1786 const char* CAppException::GetErrCodeString(void) const
1787 {
1788  switch (GetErrCode()) {
1789  case eUnsetArgs: return "eUnsetArgs";
1790  case eSetupDiag: return "eSetupDiag";
1791  case eLoadConfig: return "eLoadConfig";
1792  case eSecond: return "eSecond";
1793  case eNoRegistry: return "eNoRegistry";
1794  default: return CException::GetErrCodeString();
1795  }
1796 }
1797 
1798 
1800 {
1802 }
1803 
1804 
1806 {
1807 public:
1810 
1812  void SetIdler(INcbiIdler* idler, EOwnership own);
1813  void RunIdler(void);
1814 
1815 private:
1818 };
1819 
1820 
1821 inline
1823 {
1824  CMutexGuard guard(m_Mutex);
1825  m_Idler.reset(m_Idler.release(), own);
1826  return m_Idler.get();
1827 }
1828 
1829 
1830 inline
1832 {
1833  CMutexGuard guard(m_Mutex);
1834  m_Idler.reset(idler, own);
1835 }
1836 
1837 
1838 inline
1840 {
1841  if ( m_Idler.get() ) {
1842  CMutexGuard guard(m_Mutex);
1843  if ( m_Idler.get() ) {
1844  m_Idler->Idle();
1845  }
1846  }
1847 }
1848 
1849 
1851 
1853 {
1854  return s_IdlerWrapper.Get().GetIdler(ownership);
1855 }
1856 
1857 
1858 void SetIdler(INcbiIdler* idler, EOwnership ownership)
1859 {
1860  s_IdlerWrapper.Get().SetIdler(idler, ownership);
1861 }
1862 
1863 
1864 void RunIdler(void)
1865 {
1866  s_IdlerWrapper.Get().RunIdler();
1867 }
1868 
1869 
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:1605
void RunIdler(void)
Definition: ncbiapp.cpp:1839
CIdlerWrapper(void)
Definition: ncbiapp.cpp:1808
AutoPtr< INcbiIdler > m_Idler
Definition: ncbiapp.cpp:1817
~CIdlerWrapper(void)
Definition: ncbiapp.cpp:1809
INcbiIdler * GetIdler(EOwnership own)
Definition: ncbiapp.cpp:1822
void SetIdler(INcbiIdler *idler, EOwnership own)
Definition: ncbiapp.cpp:1831
CMutex m_Mutex
Definition: ncbiapp.cpp:1816
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:4508
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)
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:1312
CNcbiApplicationAPI * m_App
void SetFullVersion(CRef< CVersionAPI > version)
Set version data for the program.
Definition: ncbiapp.cpp:1187
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:1225
TDisableArgDesc m_DisableArgDesc
Arg desc. disabled.
void HideStdArgs(THideStdArgs hide_mask)
Set the hide mask for the Hide Std Flags.
Definition: ncbiapp.cpp:1325
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:1390
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:1340
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
Definition: ncbiapp.cpp:1786
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:1771
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:832
CVersionInfo GetVersion(void) const
Get the program version information.
Definition: ncbiapp.cpp:1197
virtual bool SetupDiag_AppSpecific(void)
Setup application specific diagnostic stream.
Definition: ncbiapp.cpp:1232
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1208
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:1239
INcbiIdler * GetIdler(EOwnership ownership)
Return currently installed idler or NULL.
Definition: ncbiapp.cpp:1852
#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:1331
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:1161
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:1369
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:1426
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:1319
virtual void AppStart(void)
Method to be called before application start.
Definition: ncbiapp.cpp:1751
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:1379
const CVersionAPI & GetFullVersion(void) const
Get the program version information.
Definition: ncbiapp.cpp:1202
ENcbiOwnership m_PhoneHomePolicy_Ownership
Phone Home Policy ownersheep.
void SetIdler(INcbiIdler *idler, EOwnership ownership)
Set new idler and ownership.
Definition: ncbiapp.cpp:1858
string m_RealExePath
Symlink-free executable path.
virtual void Idle(void)
Definition: ncbiapp.cpp:1799
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:1864
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:1780
void SetVersion(const CVersionInfo &version)
Set the version number for the program.
Definition: ncbiapp.cpp:1168
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:1613
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:7673
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:6182
void DiagHandler_Reopen(void)
Ask diagnostic handler to reopen log files if necessary.
Definition: ncbidiag.cpp:6347
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
shared_ptr< ITracerSpan > GetTracerSpan(void) const
#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
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
Definition: ncbidiag.cpp:1901
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:6332
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
Definition: ncbidiag.cpp:8150
void SetDiagErrCodeInfo(CDiagErrCodeInfo *info, bool can_delete=true)
Set handler for processing error codes.
Definition: ncbidiag.cpp:7647
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:6229
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
TDiagPostFlags SetDiagPostAllFlags(TDiagPostFlags flags)
Set global post flags to "flags".
Definition: ncbidiag.cpp:6068
#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:7907
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:8086
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:3925
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:3917
#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:3452
#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:5210
static Uint8 StringToUInt8_DataSize(const CTempString str, TStringToNumFlags flags=0)
Convert string that can contain "software" qualifiers to Uint8.
Definition: ncbistr.cpp:1530
#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:1760
string TXString
Definition: ncbistr.hpp:173
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5086
#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:5414
#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:5216
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:4671
@ fSplit_Truncate
Definition: ncbistr.hpp:2503
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2500
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:474
void SetVersionInfo(int ver_major, int ver_minor, int patch_level=0, const string &ver_name=kEmptyStr)
Set version information.
Definition: version.cpp:658
const SBuildInfo & GetBuildInfo() const
Get build info (date and tag, if set)
Definition: version.cpp:705
const CVersionInfo & GetVersionInfo() const
Get version information.
Definition: version.cpp:686
static CVersionInfo GetPackageVersion(void)
Definition: version.cpp:715
#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:728
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:774
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:691
string PrintJson(const string &appname, TPrintFlags flags=fPrintAll) const
Print version data, JSON.
Definition: version.cpp:824
@ 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
constexpr bool empty(list< Ts... >) noexcept
const string version
version string
Definition: variables.hpp:66
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=NULL, TLimitsPrintParameter parameter=NULL)
[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:1850
#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:2759
T max(T x_, T y_)
std::istream & in(std::istream &in_, double &x_)
#define BOOL
Definition: odbcinst.h:18
#define count
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 Wed Sep 04 15:05:35 2024 by modify_doxy.py rev. 669887