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

Go to the SVN repository for this file.

1 /* $Id: ncbi_param.cpp 97109 2022-06-21 13:53:08Z 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: Eugene Vasilchenko, Aleksey Grichenko
27  *
28  * File Description:
29  * Parameters storage implementation
30  *
31  */
32 
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbi_param.hpp>
36 #include <corelib/error_codes.hpp>
37 #include "ncbisys.hpp"
38 
39 
40 #define NCBI_USE_ERRCODE_X Corelib_Config
41 
42 
44 
45 //#define NCBI_PARAM_ENABLE_CONFIG_DUMP
46 
47 
48 /////////////////////////////////////////////////////////////////////////////
49 ///
50 /// Helper functions for getting values from registry/environment
51 ///
52 
53 
55 
57 {
58  s_ConfigDumpDisabled.Add(enable ? -1 : 1);
59 }
60 
61 
62 const char* kNcbiConfigPrefix = "NCBI_CONFIG__";
63 
64 // g_GetConfigXxx() functions
65 
66 namespace {
67  bool s_StringToBool(const string& value)
68  {
69  if ( !value.empty() && isdigit((unsigned char)value[0]) ) {
70  return NStr::StringToInt(value) != 0;
71  }
72  else {
73  return NStr::StringToBool(value);
74  }
75  }
76 
77  string s_GetEnvVarName(const char* section,
78  const char* variable,
79  const char* env_var_name)
80  {
81  string env_var;
82  if ( env_var_name && *env_var_name ) {
83  env_var = env_var_name;
84  }
85  else {
86  env_var = kNcbiConfigPrefix;
87  if ( section && *section ) {
88  env_var += section;
89  env_var += "__";
90  }
91  if (variable) {
92  env_var += variable;
93  }
94  }
95  NStr::ToUpper(env_var);
96  return env_var;
97  }
98 
99  const TXChar* s_GetEnv(const char* section,
100  const char* variable,
101  const char* env_var_name)
102  {
103  return NcbiSys_getenv( _T_XCSTRING(
104  s_GetEnvVarName(section, variable, env_var_name).c_str() ));
105  }
106 
107 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
108  static const char* const CONFIG_DUMP_SECTION = "NCBI";
109  static const char* const CONFIG_DUMP_VARIABLE = "CONFIG_DUMP_VARIABLES";
110  static bool s_ConfigDump = g_GetConfigFlag(CONFIG_DUMP_SECTION,
111  CONFIG_DUMP_VARIABLE,
112  0,
113  false);
114 
115  static volatile bool s_InConfigDump = false;
116 
117  inline bool s_CanDumpConfig(void)
118  {
119  return s_ConfigDumpDisabled.Get() == 0
120  && s_ConfigDump
122  }
123 #endif
124 }
125 
126 #define DUMP_CONFIG(code, data) \
127  if ( !s_InConfigDump ) { \
128  s_InConfigDump = true; \
129  ERR_POST_X(code, Note << data); \
130  s_InConfigDump = false; \
131  }
132 
133 bool NCBI_XNCBI_EXPORT g_GetConfigFlag(const char* section,
134  const char* variable,
135  const char* env_var_name,
136  bool default_value)
137 {
138 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
139  bool is_config_dump = NStr::Equal(section, CONFIG_DUMP_SECTION) &&
140  NStr::Equal(variable, CONFIG_DUMP_VARIABLE);
141 #endif
142 
143  // Check the environment first - if the name is customized CNcbiRegistry
144  // will not find it and can use INI file value instead.
145  const TXChar* str = s_GetEnv(section, variable, env_var_name);
146  if ( str && *str ) {
147  try {
148  bool value = s_StringToBool(_T_CSTRING(str));
149 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
150  if ( is_config_dump ) {
151  s_ConfigDump = value;
152  }
153  if ( s_CanDumpConfig() ) {
154  if ( section && *section ) {
155  DUMP_CONFIG(6, "NCBI_CONFIG: bool variable"
156  " [" << section << "]"
157  " " << variable <<
158  " = " << value <<
159  " from env var " <<
160  s_GetEnvVarName(section, variable, env_var_name));
161  }
162  else {
163  DUMP_CONFIG(7, "NCBI_CONFIG: bool variable "
164  " " << variable <<
165  " = " << value <<
166  " from env var");
167  }
168  }
169 #endif
170  return value;
171  }
172  catch ( ... ) {
173  // ignored
174  }
175  }
176 
177  if ( section && *section ) {
179  if ( app && app->FinishedLoadingConfig() ) {
180  const string& s = app->GetConfig().Get(section, variable);
181  if ( !s.empty() ) {
182  try {
183  bool value = s_StringToBool(s);
184 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
185  if ( is_config_dump ) {
186  s_ConfigDump = value;
187  }
188  if ( s_CanDumpConfig() ) {
189  DUMP_CONFIG(5, "NCBI_CONFIG: bool variable"
190  " [" << section << "]"
191  " " << variable <<
192  " = " << value <<
193  " from registry");
194  }
195 #endif
196  return value;
197  }
198  catch ( ... ) {
199  // ignored
200  }
201  }
202  }
203  }
204  bool value = default_value;
205 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
206  if ( is_config_dump ) {
207  s_ConfigDump = value;
208  }
209  if ( s_CanDumpConfig() ) {
210  if ( section && *section ) {
211  DUMP_CONFIG(8, "NCBI_CONFIG: bool variable"
212  " [" << section << "]"
213  " " << variable <<
214  " = " << value <<
215  " by default");
216  }
217  else {
218  DUMP_CONFIG(9, "NCBI_CONFIG: bool variable"
219  " " << variable <<
220  " = " << value <<
221  " by default");
222  }
223  }
224 #endif
225  return value;
226 }
227 
228 
229 int NCBI_XNCBI_EXPORT g_GetConfigInt(const char* section,
230  const char* variable,
231  const char* env_var_name,
232  int default_value)
233 {
234  // Check the environment first - if the name is customized CNcbiRegistry
235  // will not find it and can use INI file value instead.
236  const TXChar* str = s_GetEnv(section, variable, env_var_name);
237  if ( str && *str ) {
238  try {
240 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
241  if ( s_CanDumpConfig() ) {
242  if ( section && *section ) {
243  DUMP_CONFIG(11, "NCBI_CONFIG: int variable"
244  " [" << section << "]"
245  " " << variable <<
246  " = " << value <<
247  " from env var " <<
248  s_GetEnvVarName(section, variable, env_var_name));
249  }
250  else {
251  DUMP_CONFIG(12, "NCBI_CONFIG: int variable "
252  " " << variable <<
253  " = " << value <<
254  " from env var");
255  }
256  }
257 #endif
258  return value;
259  }
260  catch ( ... ) {
261  // ignored
262  }
263  }
264 
265  if ( section && *section ) {
267  if ( app && app->FinishedLoadingConfig() ) {
268  const string& s = app->GetConfig().Get(section, variable);
269  if ( !s.empty() ) {
270  try {
271  int value = NStr::StringToInt(s);
272 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
273  if ( s_CanDumpConfig() ) {
274  DUMP_CONFIG(10, "NCBI_CONFIG: int variable"
275  " [" << section << "]"
276  " " << variable <<
277  " = " << value <<
278  " from registry");
279  }
280 #endif
281  return value;
282  }
283  catch ( ... ) {
284  // ignored
285  }
286  }
287  }
288  }
289  int value = default_value;
290 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
291  if ( s_CanDumpConfig() ) {
292  if ( section && *section ) {
293  DUMP_CONFIG(13, "NCBI_CONFIG: int variable"
294  " [" << section << "]"
295  " " << variable <<
296  " = " << value <<
297  " by default");
298  }
299  else {
300  DUMP_CONFIG(14, "NCBI_CONFIG: int variable"
301  " " << variable <<
302  " = " << value <<
303  " by default");
304  }
305  }
306 #endif
307  return value;
308 }
309 
310 
311 double NCBI_XNCBI_EXPORT g_GetConfigDouble(const char* section,
312  const char* variable,
313  const char* env_var_name,
314  double default_value)
315 {
316  // Check the environment first - if the name is customized CNcbiRegistry
317  // will not find it and can use INI file value instead.
318  const TXChar* str = s_GetEnv(section, variable, env_var_name);
319  if ( str && *str ) {
320  try {
324 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
325  if ( s_CanDumpConfig() ) {
326  if ( section && *section ) {
327  DUMP_CONFIG(11, "NCBI_CONFIG: double variable"
328  " [" << section << "]"
329  " " << variable <<
330  " = " << value <<
331  " from env var " <<
332  s_GetEnvVarName(section, variable, env_var_name));
333  }
334  else {
335  DUMP_CONFIG(12, "NCBI_CONFIG: double variable "
336  " " << variable <<
337  " = " << value <<
338  " from env var");
339  }
340  }
341 #endif
342  return value;
343  }
344  catch ( ... ) {
345  // ignored
346  }
347  }
348 
349  if ( section && *section ) {
351  if ( app && app->FinishedLoadingConfig() ) {
352  const string& s = app->GetConfig().Get(section, variable);
353  if ( !s.empty() ) {
354  try {
355  double value = NStr::StringToDouble(s,
358 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
359  if ( s_CanDumpConfig() ) {
360  DUMP_CONFIG(10, "NCBI_CONFIG: double variable"
361  " [" << section << "]"
362  " " << variable <<
363  " = " << value <<
364  " from registry");
365  }
366 #endif
367  return value;
368  }
369  catch ( ... ) {
370  // ignored
371  }
372  }
373  }
374  }
375  double value = default_value;
376 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
377  if ( s_CanDumpConfig() ) {
378  if ( section && *section ) {
379  DUMP_CONFIG(13, "NCBI_CONFIG: double variable"
380  " [" << section << "]"
381  " " << variable <<
382  " = " << value <<
383  " by default");
384  }
385  else {
386  DUMP_CONFIG(14, "NCBI_CONFIG: int variable"
387  " " << variable <<
388  " = " << value <<
389  " by default");
390  }
391  }
392 #endif
393  return value;
394 }
395 
396 
397 string NCBI_XNCBI_EXPORT g_GetConfigString(const char* section,
398  const char* variable,
399  const char* env_var_name,
400  const char* default_value,
402 {
403  // Check the environment first - if the name is customized CNcbiRegistry
404  // will not find it and can use INI file value instead.
405  const TXChar* value = s_GetEnv(section, variable, env_var_name);
406  if ( value ) {
407 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
408  if ( s_CanDumpConfig() ) {
409  if ( section && *section ) {
410  DUMP_CONFIG(16, "NCBI_CONFIG: str variable"
411  " [" << section << "]"
412  " " << variable <<
413  " = \"" << value << "\""
414  " from env var " <<
415  s_GetEnvVarName(section, variable, env_var_name));
416  }
417  else {
418  DUMP_CONFIG(17, "NCBI_CONFIG: str variable"
419  " " << variable <<
420  " = \"" << value << "\""
421  " from env var");
422  }
423  }
424 #endif
425  if (src) *src = CParamBase::eSource_EnvVar;
426  return _T_STDSTRING(value);
427  }
428 
429  if ( section && *section ) {
431  if ( app && app->FinishedLoadingConfig() ) {
432  const string& v = app->GetConfig().Get(section, variable);
433  if ( !v.empty() ) {
434 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
435  if ( s_CanDumpConfig() ) {
436  DUMP_CONFIG(15, "NCBI_CONFIG: str variable"
437  " [" << section << "]"
438  " " << variable <<
439  " = \"" << value << "\""
440  " from registry");
441  }
442 #endif
443  if (src) *src = CParamBase::eSource_Config;
444  return v;
445  }
446  }
447  }
448  const char* dvalue = default_value? default_value: "";
449  if ( src ) *src = default_value? CParamBase::eSource_Default: CParamBase::eSource_NotSet;
450 #ifdef NCBI_PARAM_ENABLE_CONFIG_DUMP
451  if ( s_CanDumpConfig() ) {
452  if ( section && *section ) {
453  DUMP_CONFIG(18, "NCBI_CONFIG: str variable"
454  " [" << section << "]"
455  " " << variable <<
456  " = \"" << dvalue << "\""
457  " by default");
458  }
459  else {
460  DUMP_CONFIG(19, "NCBI_CONFIG: str variable"
461  " " << variable <<
462  " = \"" << dvalue << "\""
463  " by default");
464  }
465  }
466 #endif
467  return dvalue;
468 }
469 
470 const char* CParamException::GetErrCodeString(void) const
471 {
472  switch (GetErrCode()) {
473  case eParserError: return "eParserError";
474  case eBadValue: return "eBadValue";
475  case eNoThreadValue: return "eNoThreadValue";
476  case eRecursion: return "eRecursion";
477  default: return CException::GetErrCodeString();
478  }
479 }
480 
481 
CAtomicCounter_WithAutoInit –.
Definition: ncbicntr.hpp:120
char value[7]
Definition: config.c:431
static CNcbiApplicationGuard InstanceGuard(void)
Singleton method.
Definition: ncbiapp.cpp:133
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
bool FinishedLoadingConfig(void) const
Check if the application has finished loading config file (successfully or not).
TValue Add(int delta) THROWS_NONE
Atomically add value (=delta), and return new counter value.
Definition: ncbicntr.hpp:278
TValue Get(void) const THROWS_NONE
Get atomic counter value.
Definition: ncbicntr.hpp:168
static bool IsMainThreadDataInitialized(void)
Definition: ncbidiag.cpp:912
TErrCode GetErrCode(void) const
Definition: ncbiexpt.hpp:1493
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
Definition: ncbiexpt.cpp:444
int g_GetConfigInt(const char *section, const char *variable, const char *env_var_name, int default_value)
Get integer configuration value.
Definition: ncbi_param.cpp:229
double g_GetConfigDouble(const char *section, const char *variable, const char *env_var_name, double default_value)
Get double configuration value.
Definition: ncbi_param.cpp:311
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
Definition: ncbi_param.cpp:470
static void EnableConfigDump(bool enable)
Definition: ncbi_param.cpp:56
string g_GetConfigString(const char *section, const char *variable, const char *env_var_name, const char *default_value, CParamBase::EParamSource *src)
Helper functions for getting values from registry/environment.
Definition: ncbi_param.cpp:397
EParamSource
Source of the value returned by CParam::GetDefault().
Definition: ncbi_param.hpp:395
bool g_GetConfigFlag(const char *section, const char *variable, const char *env_var_name, bool default_value)
Get boolean configuration value.
Definition: ncbi_param.cpp:133
@ eNoThreadValue
Per-thread value is prohibited by flags.
Definition: ncbi_param.hpp:328
@ eRecursion
Recursion while initializing param.
Definition: ncbi_param.hpp:329
@ eParserError
Can not convert string to value.
Definition: ncbi_param.hpp:326
@ eBadValue
Unexpected parameter value.
Definition: ncbi_param.hpp:327
@ eSource_EnvVar
Environment.
Definition: ncbi_param.hpp:400
@ eSource_Config
The app. config file.
Definition: ncbi_param.hpp:401
@ eSource_NotSet
Not fully initialized.
Definition: ncbi_param.hpp:396
@ eSource_Default
Hardcoded default.
Definition: ncbi_param.hpp:397
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static bool StringToBool(const CTempString str)
Convert string to bool.
Definition: ncbistr.cpp:2819
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
char TXChar
Definition: ncbistr.hpp:172
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
#define _T_STDSTRING(x)
Definition: ncbistr.hpp:180
#define _T_CSTRING(x)
Definition: ncbistr.hpp:182
#define _T_XCSTRING(x)
Definition: ncbistr.hpp:181
static bool Equal(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Test for equality of a substring with another string.
Definition: ncbistr.hpp:5383
static string & ToUpper(string &str)
Convert string to upper case – string& version.
Definition: ncbistr.cpp:424
@ fAllowTrailingSpaces
Ignore trailing space characters.
Definition: ncbistr.hpp:297
@ fAllowLeadingSpaces
Ignore leading spaces in converted string.
Definition: ncbistr.hpp:294
@ fDecimalPosixOrLocal
StringToDouble*(): For decimal point, try both C and current locale.
Definition: ncbistr.hpp:301
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
Definition of all error codes used in corelib (xncbi.lib).
static CAtomicCounter_WithAutoInit s_ConfigDumpDisabled(0)
Helper functions for getting values from registry/environment.
#define DUMP_CONFIG(code, data)
Definition: ncbi_param.cpp:126
const char * kNcbiConfigPrefix
Definition: ncbi_param.cpp:62
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
#define NcbiSys_getenv
Definition: ncbisys.hpp:90
static const char * str(char *buf, int n)
Definition: stats.c:84
Modified on Thu Nov 30 04:56:30 2023 by modify_doxy.py rev. 669887