1 #ifndef NCBIENV__HPP 2 #define NCBIENV__HPP 3 4 /* $Id: ncbienv.hpp 574926 2018-11-20 20:23:54Z ucko $ 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, Eugene Vasilchenko 30 * 31 * 32 */ 33 34 /// @file ncbienv.hpp 35 /// Defines unified interface to application: 36 /// - Environment -- CNcbiEnvironment 37 /// - Command-line args -- CNcbiArguments 38 39 40 #include <corelib/ncbimtx.hpp> 41 #include <map> 42 #include <iterator> 43 44 /// Avoid name clash with the NCBI C Toolkit. 45 #if !defined(NCBI_OS_UNIX) || defined(HAVE_NCBI_C) 46 # if defined(GetProgramName) 47 # undef GetProgramName 48 # endif 49 # define GetProgramName GetProgramName 50 # if defined(SetProgramName) 51 # undef SetProgramName 52 # endif 53 # define SetProgramName SetProgramName 54 #endif 55 56 57 /** @addtogroup Environment 58 * 59 * @{ 60 */ 61 62 63 BEGIN_NCBI_SCOPE 64 65 66 ///////////////////////////////////////////////////////////////////////////// 67 /// 68 /// CArgumentsException -- 69 /// 70 /// Define exceptions generated by CArgumentsApplication. 71 /// 72 /// CArgumentsException inherits its basic functionality from CCoreException 73 /// and defines additional error codes for applications. 74 75 class NCBI_XNCBI_EXPORT CArgumentsException : public CCoreException 76 { 77 public: 78 /// Error types that arguments processing can generate. 79 enum EErrCode { 80 eNegativeArgc, ///< Negative argc value 81 eNoArgs ///< No arguments 82 }; 83 84 /// Translate from the error code value to its string representation. 85 virtual const char* GetErrCodeString(void) const override; 86 87 // Standard exception boilerplate code. 88 NCBI_EXCEPTION_DEFAULT(CArgumentsException, CCoreException); 89 }; 90 91 92 93 ///////////////////////////////////////////////////////////////////////////// 94 /// 95 /// CNcbiEnvironment -- 96 /// 97 /// Define the application environment. 98 /// 99 /// CNcbiEnvironment provides a data structure for storing, accessing and 100 /// modifying the environment variables accessed by the C library routine 101 /// getenv(). 102 103 class NCBI_XNCBI_EXPORT CNcbiEnvironment 104 { 105 public: 106 /// Constructor. 107 CNcbiEnvironment(void); 108 109 /// Constructor with the envp parameter. 110 CNcbiEnvironment(const char* const* envp); 111 112 /// Destructor. 113 virtual ~CNcbiEnvironment(void); 114 115 /// Reset environment. 116 /// 117 /// Delete all cached entries, load new ones from "envp" (if not NULL). 118 void Reset(const char* const* envp = 0); 119 120 /// Get environment value by name. 121 /// 122 /// If environmnent value is not cached then call "Load(name)" to load 123 /// the environmnent value. The loaded name/value pair will then be 124 /// cached, too, after the call to "Get()". 125 const string& Get(const string& name, bool* found = NULL) const; 126 127 /// Find all variable names starting with an optional prefix. 128 void Enumerate(list<string>& names, const string& prefix = kEmptyStr) 129 const; 130 131 /// Set an environment variable by name 132 /// 133 /// This will throw an exception if setting the variable fails 134 void Set(const string& name, const string& value); 135 136 /// Delete an environment variable by name 137 /// @param name environment variable name [in] 138 void Unset(const string& name); 139 140 protected: 141 /// Load value of specified environment variable. 142 virtual string Load(const string& name, bool& found) const; 143 144 private: 145 /// Cached environment <name,value> pair. 146 struct SEnvValue { SEnvValueCNcbiEnvironment::SEnvValue147 SEnvValue(void) : ptr(NULL) {} SEnvValueCNcbiEnvironment::SEnvValue148 SEnvValue(const string& v, const TXChar* p) : value(v), ptr(p) {} 149 150 string value; // cached value 151 // NULL if the corresponding environment variable is unset. 152 // kEmptyXCStr if the value was loaded from the environment. 153 // A string created by strdup() if the value came from Set(). 154 const TXChar* ptr; 155 }; 156 typedef map<string, SEnvValue> TCache; 157 mutable TCache m_Cache; 158 mutable CFastMutex m_CacheMutex; 159 }; 160 161 162 163 ///////////////////////////////////////////////////////////////////////////// 164 /// 165 /// CAutoEnvironmentVariable -- 166 /// 167 /// Establish an environment setting for a limited time. 168 /// 169 /// CAutoEnvironmentVariable establishes an environment variable setting 170 /// for the lifetime of the instance (which may be associated with a unit 171 /// test case), restoring the previous value (if any) when destroyed. 172 class NCBI_XNCBI_EXPORT CAutoEnvironmentVariable 173 { 174 public: 175 /// Initializes the environment variable passed as an argument to the 176 /// corresponding value ("1" by default) 177 /// @param var_name environment variable name [in] 178 /// @param value value to set the environment variable to [in] 179 CAutoEnvironmentVariable(const CTempString& var_name, 180 const CTempString& value = "1", 181 CNcbiEnvironment* env = NULL); 182 183 /// Destructor which restores the modifications made in the environment by 184 /// this class 185 ~CAutoEnvironmentVariable(); 186 187 private: 188 /// Affected CNcbiEnvironment instance 189 AutoPtr<CNcbiEnvironment> m_Env; 190 /// Name of the environment variable manipulated 191 string m_VariableName; 192 /// Previous value of the environment variable manipulated 193 string m_PrevValue; 194 /// Was the variable originally set at all? 195 bool m_WasSet; 196 }; 197 198 199 200 ///////////////////////////////////////////////////////////////////////////// 201 /// 202 /// CEnvironmentCleaner -- 203 /// 204 /// Remove unwanted settings from the environment, for instance to allow 205 /// test suites to start from suitably clean slates (in which case a global 206 /// static instance may be in order). 207 class NCBI_XNCBI_EXPORT CEnvironmentCleaner 208 { 209 public: 210 /// Immediately clean some settings, to be passed in as a NULL-terminated 211 /// sequence of C strings. 212 CEnvironmentCleaner(const char* s = NULL, ...); 213 214 /// Clean the specified setting. 215 void Clean(const string& name); 216 }; 217 218 219 220 ///////////////////////////////////////////////////////////////////////////// 221 /// 222 /// CNcbiArguments -- 223 /// 224 /// Store application command-line arguments & application name. 225 /// 226 /// CNcbiArgument provides a data structure for storing and accessing the 227 /// command line arguments and application name. 228 229 class NCBI_XNCBI_EXPORT CNcbiArguments 230 { 231 public: 232 /// Constructor. 233 CNcbiArguments(int argc, ///< Standard argument count 234 const char* const* argv, ///< Standard argument vector 235 const string& program_name = kEmptyStr, ///< Program name 236 const string& real_name = kEmptyStr ///< Resolved name 237 ); 238 239 /// Destructor. 240 virtual ~CNcbiArguments(void); 241 242 /// Copy constructor. 243 CNcbiArguments(const CNcbiArguments& args); 244 245 /// Assignment operator. 246 CNcbiArguments& operator= (const CNcbiArguments& args); 247 248 /// Reset arguments. 249 /// 250 /// Delete all cached args and program name. Load new ones from "argc", 251 /// "argv", "program_name", and "real_name". 252 void Reset(int argc, ///< Standard argument count 253 const char* const* argv, ///< Standard argument vector 254 const string& program_name = kEmptyStr, ///< Program name 255 const string& real_name = kEmptyStr ///< Resolved name 256 ); 257 258 /// Get size (number) of arguments. Size(void) const259 SIZE_TYPE Size(void) const { return m_Args.size(); } 260 261 /// Get the argument specified by "pos". operator [](SIZE_TYPE pos) const262 const string& operator[] (SIZE_TYPE pos) const { return m_Args[pos]; } 263 264 /// Add a new argument. 265 void Add(const string& arg); 266 267 /// Delete arguments from 1 to n. 268 void Shift(int n=1); 269 270 /// Get program name. 271 const string& GetProgramName(EFollowLinks follow_links = eIgnoreLinks) 272 const; 273 274 /// Get program base name. 275 string GetProgramBasename(EFollowLinks follow_links = eIgnoreLinks) const; 276 277 /// Get program directory name. 278 /// 279 /// Program name includes the last '/'. 280 string GetProgramDirname (EFollowLinks follow_links = eIgnoreLinks) const; 281 282 /// Set program name. If real_name is supplied, it should be the 283 /// fully resolved path to the executable (whereas program_name 284 /// may legitimately involve symlinks). 285 void SetProgramName(const string& program_name, 286 const string& real_name = kEmptyStr); 287 288 private: 289 string m_ProgramName; ///< Program name if different from the 290 ///< default m_Args[0] 291 deque<string> m_Args; ///< Queue of arguments 292 293 mutable string m_ResolvedName; 294 mutable CFastMutex m_ResolvedNameMutex; 295 }; 296 297 298 END_NCBI_SCOPE 299 300 301 /* @} */ 302 303 #endif /* NCBIENV__HPP */ 304