NCBI C++ ToolKit
ncbiapp_api.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___NCBIAPP_API__HPP
2 #define CORELIB___NCBIAPP_API__HPP
3 
4 /* $Id: ncbiapp_api.hpp 100257 2023-07-13 13:08:36Z ivanov $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Denis Vakatov, Vsevolod Sandomirskiy
30  *
31  *
32  */
33 
34 /// @file ncbiapp.hpp
35 /// Defines the CNcbiApplication and CAppException classes for creating
36 /// NCBI applications.
37 ///
38 /// The CNcbiApplicationAPI class defines the application framework and the high
39 /// high level behavior of an application, and the CAppException class is used
40 /// for the exceptions generated by CNcbiApplicationAPI.
41 
42 
43 #include <corelib/ncbiargs.hpp>
44 #include <corelib/ncbienv.hpp>
45 #include <corelib/metareg.hpp>
46 #include <corelib/version_api.hpp>
47 
48 /// Avoid preprocessor name clash with the NCBI C Toolkit.
49 #if !defined(NCBI_OS_UNIX) || defined(HAVE_NCBI_C)
50 # if defined(GetArgs)
51 # undef GetArgs
52 # endif
53 # define GetArgs GetArgs
54 #endif
55 
56 
57 /** @addtogroup AppFramework
58  *
59  * @{
60  */
61 
62 
64 
65 
66 /////////////////////////////////////////////////////////////////////////////
67 ///
68 /// CAppException --
69 ///
70 /// Define exceptions generated by CNcbiApplicationAPI.
71 ///
72 /// CAppException inherits its basic functionality from CCoreException
73 /// and defines additional error codes for applications.
74 
76 {
77 public:
78  /// Error types that an application can generate.
79  ///
80  /// These error conditions are checked for and caught inside AppMain().
81  enum EErrCode {
82  eUnsetArgs, ///< Command-line argument description not found
83  eSetupDiag, ///< Application diagnostic stream setup failed
84  eLoadConfig, ///< Registry data failed to load from config file
85  eSecond, ///< Second instance of CNcbiApplicationAPI is prohibited
86  eNoRegistry ///< Registry file cannot be opened
87  };
88 
89  /// Translate from the error code value to its string representation.
90  virtual const char* GetErrCodeString(void) const override;
91 
92  // Standard exception boilerplate code.
94 };
95 
96 
97 ///////////////////////////////////////////////////////
98 // CNcbiApplicationGuard
99 //
100 
101 
102 class CNcbiApplicationAPI;
103 
105 {
106 public:
107  ~CNcbiApplicationGuard(void);
108 
109  CNcbiApplicationAPI* Get(void) { return m_App; }
110  const CNcbiApplicationAPI* Get(void) const { return m_App; }
111  CNcbiApplicationAPI* operator->(void) { return Get(); }
112  CNcbiApplicationAPI& operator*(void) { return *Get(); }
113  operator bool(void) const { return m_App != nullptr; }
114  bool operator !(void) const { return m_App == nullptr; }
115 
116 private:
117  friend class CNcbiApplicationAPI;
119 
121  shared_ptr<CReadLockGuard> m_AppLock;
122 };
123 
124 
125 ///////////////////////////////////////////////////////
126 // CNcbiApplicationAPI
127 //
128 
129 
130 /////////////////////////////////////////////////////////////////////////////
131 ///
132 /// CNcbiApplicationAPI --
133 ///
134 /// Basic (abstract) NCBI application class.
135 ///
136 /// Defines the high level behavior of an NCBI application.
137 /// A new application is written by deriving a class from the CNcbiApplicationAPI
138 /// and writing an implementation of the Run() and maybe some other (like
139 /// Init(), Exit(), etc.) methods.
140 
142 {
143 public:
144  /// Singleton method.
145  ///
146  /// Track the instance of CNcbiApplicationAPI, and throw an exception
147  /// if an attempt is made to create another instance of the application.
148  /// @return
149  /// Current application instance.
150  /// @sa
151  /// GetInstanceMutex()
152  static CNcbiApplicationAPI* Instance(void);
153 
154  /// Singleton method.
155  ///
156  /// Get instance of the application and prevent its destruction until the lock is destroyed.
157  /// @return
158  /// Current application instance guard.
159  /// @sa
160  /// CNcbiApplicationGuard
161  static CNcbiApplicationGuard InstanceGuard(void);
162 
163  /// Mutex for application singleton object.
164  ///
165  /// Lock this mutex when calling Instance()
166  /// @return
167  /// Reference to application instance mutex.
168  /// @sa
169  /// Instance()
170  /// @deprecated Use InstanceGuard() instead.
172  static SSystemMutex& GetInstanceMutex(void);
173 
174  /// Constructor.
175  ///
176  /// Register the application instance, and reset important
177  /// application-specific settings to empty values that will
178  /// be set later.
179  explicit
180  CNcbiApplicationAPI(const SBuildInfo& build_info);
181 
182  /// Destructor.
183  ///
184  /// Clean up the application settings, flush the diagnostic stream.
185  virtual ~CNcbiApplicationAPI(void);
186 
187  /// Main function (entry point) for the NCBI application.
188  ///
189  /// You can specify where to write the diagnostics to (EAppDiagStream),
190  /// and where to get the configuration file (LoadConfig()) to load
191  /// to the application registry (accessible via GetConfig()).
192  ///
193  /// Throw exception if:
194  /// - not-only instance
195  /// - cannot load explicitly specified config.file
196  /// - SetupDiag() throws an exception
197  ///
198  /// If application name is not specified a default of "ncbi" is used.
199  /// Certain flags such as -logfile, -conffile and -version are special so
200  /// AppMain() processes them separately.
201  /// @param argc
202  /// Argument count [argc in a regular main(argc, argv)].
203  /// @param argv
204  /// Argument vector [argv in a regular main(argc, argv)].
205  /// @param envp
206  /// Environment pointer [envp in a regular main(argc, argv, envp)];
207  /// a null pointer (the default) corresponds to the standard system
208  /// array (environ on most Unix platforms).
209  /// @param diag
210  /// Specify diagnostic stream.
211  /// @param conf
212  /// Specify registry to load, as per LoadConfig(). The default is an
213  /// empty string, requesting automatic detection; it is also possible
214  /// to pass a specific name (optionally qualified) or a NULL pointer
215  /// (disabling application-specific registry lookup altogether).
216  /// @param name
217  /// Specify application name, used in diagnostics and automatic
218  /// registry searching.
219  /// @return
220  /// Exit code from Run(). Can also return non-zero value if application
221  /// threw an exception.
222  /// @sa
223  /// LoadConfig(), Init(), Run(), Exit()
224  int AppMain
225  (int argc,
226  const char* const* argv,
227  const char* const* envp = 0,
229  const char* conf = NcbiEmptyCStr,
230  const string& name = NcbiEmptyString
231  );
232 
233 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
234  int AppMain
235  (int argc,
236  const TXChar* const* argv,
237  const TXChar* const* envp = 0,
239  const TXChar* conf = NcbiEmptyXCStr,
240  const TXString& name = NcbiEmptyXString
241  );
242 #endif
243 
244  /// Initialize the application.
245  ///
246  /// The default behavior of this is "do nothing". If you have special
247  /// initialization logic that needs to be peformed, then you must override
248  /// this method with your own logic.
249  virtual void Init(void);
250 
251  /// Run the application.
252  ///
253  /// It is defined as a pure virtual method -- so you must(!) supply the
254  /// Run() method to implement the application-specific logic.
255  /// @return
256  /// Exit code.
257  virtual int Run(void) = 0;
258 
259  /// Test run the application.
260  ///
261  /// It is only supposed to test if the Run() is possible,
262  /// or makes sense: that is, test all preconditions etc.
263  /// @return
264  /// Exit code.
265  virtual int DryRun(void);
266 
267  /// Cleanup on application exit.
268  ///
269  /// Perform cleanup before exiting. The default behavior of this is
270  /// "do nothing". If you have special cleanup logic that needs to be
271  /// performed, then you must override this method with your own logic.
272  virtual void Exit(void);
273 
274  /// Get the application's cached unprocessed command-line arguments.
275  const CNcbiArguments& GetArguments(void) const;
276 
277  /// Get parsed command line arguments.
278  ///
279  /// Get command line arguments parsed according to the arg descriptions
280  /// set by SetupArgDescriptions(). Throw exception if no descriptions
281  /// have been set.
282  /// @return
283  /// The CArgs object containing parsed cmd.-line arguments.
284  /// @sa
285  /// SetupArgDescriptions().
286  virtual const CArgs& GetArgs(void) const;
287 
288  /// Get the application's cached environment.
289  const CNcbiEnvironment& GetEnvironment(void) const;
290 
291  /// Get a non-const copy of the application's cached environment.
292  CNcbiEnvironment& SetEnvironment(void);
293 
294  /// Set a specified environment variable by name
295  void SetEnvironment(const string& name, const string& value);
296 
297  /// Check if the config file has been loaded
298  bool HasLoadedConfig(void) const;
299 
300  /// Check if the application has finished loading config file
301  /// (successfully or not).
302  bool FinishedLoadingConfig(void) const;
303 
304  /// Get the application's cached configuration parameters (read-only).
305  ///
306  /// Application also can use protected GetRWConfig() to get read-write
307  // access to the configuration parameters.
308  /// @sa
309  /// GetRWConfig
310  const CNcbiRegistry& GetConfig(void) const;
311 
312  /// @deprecated Please use the const version of GetConfig() or protected GetRWConfig()
313  //NCBI_DEPRECATED
314  CNcbiRegistry& GetConfig(void);
315 
316  /// Get the full path to the configuration file (if any) we ended
317  /// up using.
318  const string& GetConfigPath(void) const;
319 
320  /// Reload the configuration file. By default, does nothing if
321  /// the file has the same size and date as before.
322  ///
323  /// Note that this may lose other data stored in the registry!
324  ///
325  /// @param flags
326  /// Controls how aggressively to reload.
327  /// @param reg_flags
328  /// Flags to use when parsing the registry; ignored if the registry
329  /// was already cached (as it should normally have been).
330  /// @return
331  /// TRUE if a reload actually occurred.
332  bool ReloadConfig(CMetaRegistry::TFlags flags
335 
336  /// Flush the in-memory diagnostic stream (for "eDS_ToMemory" case only).
337  ///
338  /// In case of "eDS_ToMemory", the diagnostics is stored in
339  /// the internal application memory buffer ("m_DiagStream").
340  /// Call this function to dump all the diagnostics to stream "os" and
341  /// purge the buffer.
342  /// @param os
343  /// Output stream to dump diagnostics to. If it is NULL, then
344  /// nothing will be written to it (but the buffer will still be purged).
345  /// @param close_diag
346  /// If "close_diag" is TRUE, then also destroy "m_DiagStream".
347  /// @return
348  /// Total number of bytes actually written to "os".
349  SIZE_TYPE FlushDiag(CNcbiOstream* os, bool close_diag = false);
350 
351  /// Get the application's "display" name.
352  ///
353  /// Get name of this application, suitable for displaying
354  /// or for using as the base name for other files.
355  /// Will be the 'name' argument of AppMain if given.
356  /// Otherwise will be taken from the actual name of the application file
357  /// or argv[0].
358  const string& GetProgramDisplayName(void) const;
359 
360  /// Get the application's executable path.
361  ///
362  /// The path to executable file of this application.
363  /// Return empty string if not possible to determine this path.
364  const string& GetProgramExecutablePath(EFollowLinks follow_links = eIgnoreLinks) const;
365 
367  eBaseName, ///< per GetProgramDisplayName
368  eFullName, ///< per GetProgramExecutablePath(eIgnoreLinks)
369  eRealName ///< per GetProgramExecutablePath(eFollowLinks)
370  };
371  static string GetAppName(EAppNameType name_type = eBaseName,
372  int argc = 0, const char* const* argv = NULL);
373 
374  /// Get the program version information.
375  ///
376  /// @sa SetVersion, SetFullVersion
377  CVersionInfo GetVersion(void) const;
378 
379  /// Get the program version information.
380  const CVersionAPI& GetFullVersion(void) const;
381 
382  /// Check if it is a test run.
383  bool IsDryRun(void) const;
384 
385  /// Setup application specific diagnostic stream.
386  ///
387  /// Called from SetupDiag when it is passed the eDS_AppSpecific parameter.
388  /// Currently, this calls SetupDiag(eDS_ToStderr) to setup diagonistic
389  /// stream to the std error channel.
390  /// @return
391  /// TRUE if successful, FALSE otherwise.
392  /// @deprecated
393  NCBI_DEPRECATED virtual bool SetupDiag_AppSpecific(void);
394 
395  /// Add callback to be executed from CNcbiApplicationAPI destructor.
396  /// @note It is executed earlier, at CNcbiApplication destructor; and, it
397  /// may be executed even earlier from destructors of other
398  /// CNcbiApplicationAPI-derived classes.
399  /// @sa CNcbiActionGuard, ExecuteOnExitActions()
400  template<class TFunc> void AddOnExitAction(TFunc func)
401  {
402  m_OnExitActions.AddAction(func);
403  }
404 
405 protected:
406  friend class CNcbiApplicationGuard;
407  static CRWLock& GetInstanceLock(void);
408 
409  /// Result of PreparseArgs()
411  ePreparse_Continue, ///< Continue application execution
412  ePreparse_Exit ///< Exit the application with zero exit code
413  };
414 
415  /// Check the command line arguments before parsing them.
416  /// @sa EPreparseArgs
417  virtual EPreparseArgs PreparseArgs(int argc,
418  const char* const* argv);
419 
420  /// Disable argument descriptions.
421  ///
422  /// Call with a bit flag set if you do not want std AND user
423  /// cmd.line args to be parsed.
424  /// Note that by default the parsing of cmd.line args are enabled.
426  fDisableStdArgs = 0x01 ///< (-logfile, -conffile, -version etc)
427  };
428  typedef int TDisableArgDesc; ///< Binary OR of "EDisableArgDesc"
429  void DisableArgDescriptions(TDisableArgDesc disable = fDisableStdArgs);
430 
431  /// Which standard flag's descriptions should not be displayed in
432  /// the usage message.
433  ///
434  /// Do not display descriptions of the standard flags such as the
435  /// -h, -logfile, -conffile, -version
436  /// flags in the usage message. Note that you still can pass them in
437  /// the command line.
439  fHideLogfile = CArgDescriptions::fHideLogfile, ///< Hide log file description
440  fHideConffile = CArgDescriptions::fHideConffile, ///< Hide configuration file description
441  fHideVersion = CArgDescriptions::fHideVersion, ///< Hide version description
442  fHideFullVersion = CArgDescriptions::fHideFullVersion, ///< Hide full version description
443  fHideDryRun = CArgDescriptions::fHideDryRun, ///< Hide dryrun description
444  fHideHelp = CArgDescriptions::fHideHelp, ///< Hide help description
445  fHideFullHelp = CArgDescriptions::fHideFullHelp, ///< Hide full help description
446  fHideXmlHelp = CArgDescriptions::fHideXmlHelp, ///< Hide XML help description
447  fHideAll = CArgDescriptions::fHideAll ///< Hide all standard argument descriptions
448  };
449  typedef int THideStdArgs; ///< Binary OR of "EHideStdArgs"
450 
451  /// Set the hide mask for the Hide Std Flags.
452  void HideStdArgs(THideStdArgs hide_mask);
453 
454  /// Flags to adjust standard I/O streams' behaviour.
455  enum EStdioSetup {
456  fNoSyncWithStdio = 0x01,
457  ///< Turn off synchronizing of "C++" cin/cout/cerr streams with
458  ///< their "C" counterparts, possibly making the former not thread-safe.
459 
460  fDefault_CinBufferSize = 0x02,
461  ///< Use compiler-specific default of Cin buffer size.
462  fBinaryCin = 0x04, ///< treat standard input as binary
463  fBinaryCout = 0x08, ///< treat standard output as binary
464 
465  fDefault_SyncWithStdio = 0x00, ///< @deprecated @sa fNoSyncWithStdio
466  };
467  typedef int TStdioSetupFlags; ///< Binary OR of "EStdioSetup"
468 
469  /// Adjust the behavior of standard I/O streams.
470  ///
471  /// Unless this function is called, the behaviour of "C++" Cin/Cout/Cerr
472  /// streams will be the same regardless of the compiler used.
473  ///
474  /// IMPLEMENTATION NOTE: Do not call this function more than once
475  /// and from places other than App's constructor.
476  void SetStdioFlags(TStdioSetupFlags stdio_flags);
477 
478  /// Set the version number for the program.
479  ///
480  /// If not set, a default of 0.0.teamcity_build_number is used.
481  /// @note
482  /// This function should be used from constructor of CNcbiApplicationAPI
483  /// derived class, otherwise command-like arguments "-version" and
484  /// "-version-full" will not work as expected.
485  /// @sa GetVersion, NCBI_APP_SET_VERSION, NCBI_APP_SET_VERSION_AUTO
486  void SetVersion(const CVersionInfo& version);
487  void SetVersion(const CVersionInfo& version, const SBuildInfo& build_info);
488  NCBI_DEPRECATED void SetVersionByBuild(int major);
489 
490  /// Set version data for the program.
491  ///
492  /// @note
493  /// This function should be used from constructor of CNcbiApplicationAPI
494  /// derived class, otherwise command-like arguments "-version" and
495  /// "-version-full" will not work as expected.
496  /// @sa GetVersion
497  void SetFullVersion( CRef<CVersionAPI> version);
498 
499  /// Setup the command line argument descriptions.
500  ///
501  /// Call from the Init() method. The passed "arg_desc" will be owned
502  /// by this class, and it will be deleted by ~CNcbiApplicationAPI(),
503  /// or if SetupArgDescriptions() is called again.
504  virtual void SetupArgDescriptions(CArgDescriptions* arg_desc);
505 
506  /// Get argument descriptions (set by SetupArgDescriptions)
507  const CArgDescriptions* GetArgDescriptions(void) const;
508 
509  /// Setup the application diagnostic stream.
510  /// @return
511  /// TRUE if successful, FALSE otherwise.
512  /// @deprecated
513  NCBI_DEPRECATED bool SetupDiag(EAppDiagStream diag);
514 
515  /// Load settings from the configuration file to the registry.
516  ///
517  /// This method is called from inside AppMain() to load (add) registry
518  /// settings from the configuration file specified as the "conf" arg
519  /// passed to AppMain(). The "conf" argument has the following special
520  /// meanings:
521  /// - NULL -- don't try to load an application-specific registry
522  /// from any file at all.
523  /// - non-empty -- if "conf" contains a path, then try to load from the
524  /// conf.file of name "conf" (only!). Else - see NOTE.
525  /// TIP: if the path is not fully qualified then:
526  /// if it starts from "../" or "./" -- look starting
527  /// from the current working dir.
528  /// - empty -- compose conf.file name from the application name
529  /// plus ".ini". If it does not match an existing
530  /// file, then try to strip file extensions, e.g. for
531  /// "my_app.cgi.exe" -- try subsequently:
532  /// "my_app.cgi.exe.ini", "my_app.cgi.ini", "my_app.ini".
533  ///
534  /// Regardless, this method normally loads global settings
535  /// from .ncbirc or ncbi.ini when reg_flags contains fWithNcbirc
536  /// (as it typically does), even if conf is NULL.
537  ///
538  /// NOTE:
539  /// If "conf" arg is empty or non-empty, but without path, then
540  /// the Toolkit will try to look for it in several potentially
541  /// relevant directories, as described in <corelib/metareg.hpp>.
542  ///
543  /// Throw an exception if "conf" is non-empty, and cannot open file.
544  /// Throw an exception if file exists, but contains invalid entries.
545  /// @param reg
546  /// The loaded registry is returned via the reg parameter.
547  /// @param conf
548  /// The configuration file to loaded the registry entries from.
549  /// @param reg_flags
550  /// Flags for loading the registry
551  /// @return
552  /// TRUE only if the file was non-NULL, found and successfully read.
553  /// @sa
554  /// CMetaRegistry::GetDefaultSearchPath
555  virtual bool LoadConfig(CNcbiRegistry& reg, const string* conf,
556  CNcbiRegistry::TFlags reg_flags);
557 
558  /// Load settings from the configuration file to the registry.
559  ///
560  /// CNcbiApplicationAPI::LoadConfig(reg, conf) just calls
561  /// LoadConfig(reg, conf, IRegistry::fWithNcbirc).
562  virtual bool LoadConfig(CNcbiRegistry& reg, const string* conf);
563 
564  /// Get the application's cached configuration parameters,
565  /// accessible for read-write for an application's internal use only.
566  /// @sa
567  /// GetConfig
568  CNcbiRegistry& GetRWConfig(void);
569 
570  /// Set program's display name.
571  ///
572  /// Set up application name suitable for display or as a basename for
573  /// other files. It can also be set by the user when calling AppMain().
574  void SetProgramDisplayName(const string& app_name);
575 
576  /// Find the application's executable file.
577  ///
578  /// Find the path and name of the executable file that this application
579  /// is running from. Will be accessible by GetArguments().GetProgramName().
580  /// @param argc
581  /// Standard argument count "argc".
582  /// @param argv
583  /// Standard argument vector "argv".
584  /// @param real_path
585  /// If non-NULL, will get the fully resolved path to the executable.
586  /// @return
587  /// Name of application's executable file (may involve symlinks).
588  /// @sa
589  /// GetArguments().GetProgramName(), GetProgramExecutablePath
590  static string FindProgramExecutablePath(int argc, const char* const* argv,
591  string* real_path = 0);
592 
593  /// Method to be called before application start.
594  /// Can be used to set DiagContext properties to be printed
595  /// in the application start message (e.g. host|host_ip_addr,
596  /// client_ip and session_id for CGI applications).
597  virtual void AppStart(void);
598 
599  /// Method to be called before application exit.
600  /// Can be used to set DiagContext properties to be printed
601  /// in the application stop message (exit_status, exit_signal,
602  /// exit_code).
603  virtual void AppStop(int exit_code);
604 
605  /// When to return a user-set exit code
606  enum EExitMode {
607  eNoExits, ///< never (stick to existing logic)
608  eExceptionalExits, ///< when an (uncaught) exception occurs
609  eAllExits ///< always (ignoring Run's return value)
610  };
611  /// Force the program to return a specific exit code later, either
612  /// when it exits due to an exception or unconditionally. In the
613  /// latter case, Run's return value will be ignored.
614  void SetExitCode(int exit_code, EExitMode when = eExceptionalExits);
615 
616  enum EAppFlags {
617  fSkipSafeStaticDestroy = 1 << 0
618  };
619  typedef int TAppFlags;
620  void SetAppFlags(TAppFlags flags) { m_AppFlags = flags; }
621 
622  /// Should only be called from the destructors of classes derived from
623  /// CNcbiApplicationAPI - if it is necessary to access their data members
624  /// and virtual methods; or to dynamic_cast<> from the base app class.
625  /// @sa AddOnExitAction()
626  void ExecuteOnExitActions();
627 
628 private:
629  /// Read standard NCBI application configuration settings.
630  ///
631  /// [NCBI]: HeapSizeLimit, CpuTimeLimit
632  /// [DEBUG]: ABORT_ON_THROW, DIAG_POST_LEVEL, MessageFile
633  /// @param reg
634  /// Registry to read from. If NULL, use the current registry setting.
635  void x_HonorStandardSettings(IRegistry* reg = 0);
636 
637  /// Read switches that are stored in m_LogOptions from registry and
638  /// environment
639  void x_ReadLogOptions();
640 
641  /// Log environment, registry, command arguments, path
642  void x_LogOptions(int event);
643 
644  /// Setup C++ standard I/O streams' behaviour.
645  ///
646  /// Called from AppMain() to do compiler-specific optimization
647  /// for C++ I/O streams. For example, since SUN WorkShop STL stream
648  /// library has significant performance loss when sync_with_stdio is
649  /// TRUE (default), so we turn it off. Another, for GCC version greater
650  /// than 3.00 we forcibly set cin stream buffer size to 4096 bytes -- which
651  /// boosts the performance dramatically.
652  void x_SetupStdio(void);
653 
654  void x_AddDefaultArgs(void);
655 
656  // Wrappers for parts of AppMain() called with or without try/catch
657  // depending on settings.
658  void x_TryInit(EAppDiagStream diag, const char* conf);
659  void x_TryMain(EAppDiagStream diag,
660  const char* conf,
661  int* exit_code,
662  bool* got_exception);
663 
664  static CNcbiApplicationAPI*m_Instance; ///< Current app. instance
665  CRef<CVersionAPI> m_Version; ///< Program version
666  unique_ptr<CNcbiEnvironment> m_Environ; ///< Cached application env.
667  CRef<CNcbiRegistry> m_Config; ///< Guaranteed to be non-NULL
668  unique_ptr<CNcbiOstream> m_DiagStream; ///< Opt., aux., see eDS_ToMemory
669  unique_ptr<CNcbiArguments> m_Arguments; ///< Command-line arguments
670  unique_ptr<CArgDescriptions> m_ArgDesc; ///< Cmd.-line arg descriptions
671  unique_ptr<CArgs> m_Args; ///< Parsed cmd.-line args
672  TDisableArgDesc m_DisableArgDesc; ///< Arg desc. disabled
673  THideStdArgs m_HideArgs; ///< Std cmd.-line flags to hide
674  TStdioSetupFlags m_StdioFlags; ///< Std C++ I/O adjustments
675  char* m_CinBuffer; ///< Cin buffer if changed
676  string m_ProgramDisplayName; ///< Display name of app
677  string m_ExePath; ///< Program executable path
678  string m_RealExePath; ///< Symlink-free executable path
679  mutable string m_LogFileName; ///< Log file name
680  string m_ConfigPath; ///< Path to .ini file used
681  int m_ExitCode; ///< Exit code to force
682  EExitMode m_ExitCodeCond; ///< When to force it (if ever)
683  bool m_DryRun; ///< Dry run
684  string m_DefaultConfig; ///< conf parameter to AppMain
685  bool m_ConfigLoaded; ///< Finished loading config
686  const char* m_LogFile; ///< Logfile if set in the command line
687  int m_LogOptions; ///< logging of env, reg, args, path
688  CNcbiActionGuard m_OnExitActions; ///< Actions executed on app destruction
689  TAppFlags m_AppFlags = 0;
690 };
691 
692 /// Interface for application idler.
694 public:
695  virtual ~INcbiIdler(void) {}
696 
697  // Perform any actions. Called by RunIdle().
698  virtual void Idle(void) = 0;
699 };
700 
701 
702 /// Default idler.
704 {
705 public:
706  CDefaultIdler(void) {}
707  virtual ~CDefaultIdler(void) {}
708 
709  virtual void Idle(void);
710 };
711 
712 
713 /// Return currently installed idler or NULL. Update idler ownership
714 /// according to the flag.
716 
717 /// Set new idler and ownership.
719  EOwnership ownership = eTakeOwnership);
720 
721 /// Execute currently installed idler if any.
722 NCBI_XNCBI_EXPORT void RunIdler(void);
723 
724 
725 /* @} */
726 
727 
728 
729 /////////////////////////////////////////////////////////////////////////////
730 // IMPLEMENTATION of INLINE functions
731 /////////////////////////////////////////////////////////////////////////////
732 
733 
735 {
736  return *m_Arguments;
737 }
738 
740 {
741  return *m_Environ;
742 }
743 
745 {
746  return *m_Environ;
747 }
748 
750 {
751  return *m_Config;
752 }
753 
754 /// @deprecated
756 {
757  return *m_Config;
758 }
759 
761 {
762  return *m_Config;
763 }
764 
765 inline const string& CNcbiApplicationAPI::GetConfigPath(void) const
766 {
767  return m_ConfigPath;
768 }
769 
771 {
772  return !m_ConfigPath.empty();
773 }
774 
776 {
777  return m_ConfigLoaded;
778 }
779 
781 {
782  return CMetaRegistry::Reload(GetConfigPath(), GetRWConfig(), flags, reg_flags);
783 }
784 
785 inline const string& CNcbiApplicationAPI::GetProgramDisplayName(void) const
786 {
787  return m_ProgramDisplayName;
788 }
789 
790 inline const string&
792 {
793  return follow_links == eFollowLinks ? m_RealExePath : m_ExePath;
794 }
795 
796 
798 {
799  return m_ArgDesc.get();
800 }
801 
802 
803 inline bool CNcbiApplicationAPI::IsDryRun(void) const
804 {
805  return m_DryRun;
806 }
807 
808 
809 #ifndef CORELIB___NCBIAPP__HPP
810 # define CNcbiApplication CNcbiApplicationAPI
811 #endif
812 
814 
815 #endif /* CORELIB___NCBIAPP_API__HPP */
#define bool
Definition: bool.h:34
CAppException –.
Definition: ncbiapp_api.hpp:76
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgs –.
Definition: ncbiargs.hpp:379
CCoreException –.
Definition: ncbiexpt.hpp:1476
Default idler.
static bool Reload(const string &path, IRWRegistry &reg, TFlags flags=0, TRegFlags reg_flags=0)
Reload the configuration file "path".
Definition: metareg.hpp:228
@ fReloadIfChanged
Reload if time or size has changed.
Definition: metareg.hpp:53
int TFlags
Binary OR of "EFlags".
Definition: metareg.hpp:57
CNcbiActionGuard class Executes registered callbacks on request or on destruction.
Definition: ncbimisc.hpp:1387
CNcbiApplicationAPI –.
CNcbiArguments –.
Definition: ncbienv.hpp:230
CNcbiEnvironment –.
Definition: ncbienv.hpp:104
CNcbiRegistry –.
Definition: ncbireg.hpp:913
CRWLock –.
Definition: ncbimtx.hpp:953
CVersionInfo –.
Interface for application idler.
IRegistry –.
Definition: ncbireg.hpp:73
char value[7]
Definition: config.c:431
static uch flags
static void Init(void)
Definition: cursor6.c:76
void AddOnExitAction(TFunc func)
Add callback to be executed from CNcbiApplicationAPI destructor.
EHideStdArgs
Which standard flag's descriptions should not be displayed in the usage message.
bool HasLoadedConfig(void) const
Check if the config file has been loaded.
unique_ptr< CNcbiArguments > m_Arguments
Command-line arguments.
bool ReloadConfig(CMetaRegistry::TFlags flags=CMetaRegistry::fReloadIfChanged, IRegistry::TFlags reg_flags=IRegistry::fWithNcbirc)
Reload the configuration file.
CNcbiApplicationAPI * m_App
unique_ptr< CNcbiOstream > m_DiagStream
Opt., aux., see eDS_ToMemory.
int TStdioSetupFlags
Binary OR of "EStdioSetup".
NCBI_EXCEPTION_DEFAULT(CAppException, CCoreException)
string m_ConfigPath
Path to .ini file used.
CNcbiActionGuard m_OnExitActions
Actions executed on app destruction.
TDisableArgDesc m_DisableArgDesc
Arg desc. disabled.
TStdioSetupFlags m_StdioFlags
Std C++ I/O adjustments.
string m_LogFileName
Log file name.
friend class CNcbiApplicationGuard
string m_ProgramDisplayName
Display name of app.
CNcbiApplicationAPI * operator->(void)
virtual int Run(void)=0
Run the application.
int m_LogOptions
logging of env, reg, args, path
void SetAppFlags(TAppFlags flags)
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.
EExitMode
When to return a user-set exit code.
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
EStdioSetup
Flags to adjust standard I/O streams' behaviour.
int m_ExitCode
Exit code to force.
char * m_CinBuffer
Cin buffer if changed.
EPreparseArgs
Result of PreparseArgs()
INcbiIdler * GetIdler(EOwnership ownership=eNoOwnership)
Return currently installed idler or NULL.
Definition: ncbiapp.cpp:1819
const char * m_LogFile
Logfile if set in the command line.
bool m_DryRun
Dry run.
EErrCode
Error types that an application can generate.
Definition: ncbiapp_api.hpp:81
const CArgDescriptions * GetArgDescriptions(void) const
Get argument descriptions (set by SetupArgDescriptions)
shared_ptr< CReadLockGuard > m_AppLock
unique_ptr< CNcbiEnvironment > m_Environ
Cached application env.
const string & GetConfigPath(void) const
Get the full path to the configuration file (if any) we ended up using.
unique_ptr< CArgs > m_Args
Parsed cmd.-line args.
int THideStdArgs
Binary OR of "EHideStdArgs".
bool FinishedLoadingConfig(void) const
Check if the application has finished loading config file (successfully or not).
EFollowLinks
Whether to follow symbolic links (also known as shortcuts or aliases)
Definition: ncbimisc.hpp:143
const string & GetProgramDisplayName(void) const
Get the application's "display" name.
bool IsDryRun(void) const
Check if it is a test run.
EExitMode m_ExitCodeCond
When to force it (if ever)
CNcbiRegistry & GetRWConfig(void)
Get the application's cached configuration parameters, accessible for read-write for an application's...
const CNcbiApplicationAPI * Get(void) const
unique_ptr< CArgDescriptions > m_ArgDesc
Cmd.-line arg descriptions.
virtual void Idle(void)=0
EDisableArgDesc
Disable argument descriptions.
int TDisableArgDesc
Binary OR of "EDisableArgDesc".
CNcbiApplicationAPI * Get(void)
CRef< CNcbiRegistry > m_Config
Guaranteed to be non-NULL.
static CNcbiApplicationAPI * m_Instance
Current app. instance.
CNcbiApplicationAPI & operator*(void)
void SetIdler(INcbiIdler *idler, EOwnership ownership=eTakeOwnership)
Set new idler and ownership.
Definition: ncbiapp.cpp:1825
virtual ~CDefaultIdler(void)
virtual ~INcbiIdler(void)
string m_RealExePath
Symlink-free executable path.
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:1831
bool m_ConfigLoaded
Finished loading config.
THideStdArgs m_HideArgs
Std cmd.-line flags to hide.
string m_DefaultConfig
conf parameter to AppMain
CRef< CVersionAPI > m_Version
Program version.
@ eNoExits
never (stick to existing logic)
@ eExceptionalExits
when an (uncaught) exception occurs
@ ePreparse_Continue
Continue application execution.
@ eUnsetArgs
Command-line argument description not found.
Definition: ncbiapp_api.hpp:82
@ eSecond
Second instance of CNcbiApplicationAPI is prohibited.
Definition: ncbiapp_api.hpp:85
@ eLoadConfig
Registry data failed to load from config file.
Definition: ncbiapp_api.hpp:84
@ eSetupDiag
Application diagnostic stream setup failed.
Definition: ncbiapp_api.hpp:83
@ eIgnoreLinks
Do not follow symbolic links.
Definition: ncbimisc.hpp:144
@ eFollowLinks
Follow symbolic links.
Definition: ncbimisc.hpp:145
@ eFullName
per GetProgramExecutablePath(eIgnoreLinks)
@ 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
@ fHideAll
Hide all standard argument descriptions.
Definition: ncbiargs.hpp:1072
@ fHideFullVersion
Hide full version description.
Definition: ncbiargs.hpp:1067
@ fHideConffile
Hide configuration file description.
Definition: ncbiargs.hpp:1065
@ fHideHelp
Hide help description.
Definition: ncbiargs.hpp:1069
@ fHideXmlHelp
Hide XML help description.
Definition: ncbiargs.hpp:1071
@ fHideLogfile
Hide log file description.
Definition: ncbiargs.hpp:1064
@ fHideVersion
Hide version description.
Definition: ncbiargs.hpp:1066
@ fHideFullHelp
Hide full help description.
Definition: ncbiargs.hpp:1070
@ fHideDryRun
Hide dryrun description.
Definition: ncbiargs.hpp:1068
#define NULL
Definition: ncbistd.hpp:225
EAppDiagStream
Where to write the application's diagnostics to.
Definition: ncbidiag.hpp:1780
@ eDS_Default
Try standard log file (app.name + ".log") in /log/, use stderr on failure.
Definition: ncbidiag.hpp:1790
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
Definition: ncbiexpt.cpp:757
#define NCBI_DEPRECATED
int TFlags
Binary OR of "EFlags".
Definition: ncbireg.hpp:107
@ fWithNcbirc
Include .ncbirc (used only by CNcbiReg.)
Definition: ncbireg.hpp:93
#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
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
#define NcbiEmptyCStr
Definition: ncbistr.hpp:59
#define NcbiEmptyXCStr
Definition: ncbistr.hpp:184
#define NcbiEmptyXString
Definition: ncbistr.hpp:185
char TXChar
Definition: ncbistr.hpp:172
string TXString
Definition: ncbistr.hpp:173
#define NcbiEmptyString
Definition: ncbistr.hpp:122
enum ENcbiOwnership EOwnership
Ownership relations between objects.
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
static int version
Definition: mdb_load.c:29
CMetaRegistry: Singleton class for loading CRegistry data from files; keeps track of what it loaded f...
const TYPE & Get(const CNamedParameterList *param)
#define GetArgs
Avoid preprocessor name clash with the NCBI C Toolkit.
Definition: ncbiapp_api.hpp:53
Defines command line argument related classes.
Defines unified interface to application:
This class allows to add build info (date and tag) to application version.
Definition: version_api.hpp:62
Modified on Thu Dec 07 10:09:16 2023 by modify_doxy.py rev. 669887