0028110: Configuration - specify Unicode charset instead of multibyte in project...
[occt.git] / src / OSD / OSD_Environment.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
57c28b61 15#ifndef _WIN32
7fd59977 16
42cf5bc1 17#include <OSD_Environment.hxx>
18#include <OSD_OSDError.hxx>
19#include <OSD_WhoAmI.hxx>
7fd59977 20#include <Standard_ConstructionError.hxx>
21#include <Standard_Failure.hxx>
22#include <Standard_Mutex.hxx>
42cf5bc1 23#include <Standard_NullObject.hxx>
24#include <TCollection_AsciiString.hxx>
8582eb08 25#include <NCollection_UtfString.hxx>
7fd59977 26
42cf5bc1 27#include <errno.h>
7fd59977 28#include <stdio.h>
42cf5bc1 29#include <stdlib.h>
7fd59977 30#include <string.h>
7fd59977 31static const OSD_WhoAmI Iam = OSD_WEnvironment;
32
33// ----------------------------------------------------------------------
34//
35// Updated by : JPT Dec,7 1992
36// What : OSD_Environment::OSD_Environment
37// (const TCollection_AsciiString& Name,
38// const TCollection_AsciiString& Value)
39// Value could contain the character $ (Ex setenv a = $c)
40//
41// ----------------------------------------------------------------------
42// Create object
43
44OSD_Environment::OSD_Environment()
45{
46}
47
48
49// ----------------------------------------------------------------------
50// Constructor
51// ----------------------------------------------------------------------
52
53OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name)
54{
55
56 if (!Name.IsAscii() || Name.Search("$") != -1 )
57 Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument");
58
59 myName = Name;
60}
61
62
63// ----------------------------------------------------------------------
64// Create an environment variable and initialize it
65// ----------------------------------------------------------------------
66
67OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name,
68 const TCollection_AsciiString& Value)
69{
70
71 if (!Name.IsAscii() || !Value.IsAscii() ||
72// JPT : Dec-7-1992 Name.Search("$") != -1 || Value.Search("$") != -1)
73 Name.Search("$") != -1 )
74 Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument");
75
76 myName = Name;
77 myValue = Value;
78}
79
80
81// ----------------------------------------------------------------------
82// Returns the name of the symbol
83// ----------------------------------------------------------------------
84
85TCollection_AsciiString OSD_Environment::Name () const
86{
87 return myName;
88}
89
90// ----------------------------------------------------------------------
91// Set new value for environment variable
92// ----------------------------------------------------------------------
93
94void OSD_Environment::SetName (const TCollection_AsciiString& Name)
95{
96 myError.Reset();
97 if (!Name.IsAscii() || Name.Search("$") != -1 )
98 Standard_ConstructionError::Raise("OSD_Environment::SetName: bad argument");
99
100 myName = Name;
101}
102
103// ----------------------------------------------------------------------
104// Change value
105// ----------------------------------------------------------------------
106
107void OSD_Environment::SetValue (const TCollection_AsciiString& Value)
108{
109 if (!Value.IsAscii() || Value.Search("$") != -1)
110 Standard_ConstructionError::Raise("OSD_Environment::Change: bad argument");
111
112 myValue = Value;
113}
114
115// ----------------------------------------------------------------------
116// Get environment variable physically
117// ----------------------------------------------------------------------
118
119TCollection_AsciiString OSD_Environment::Value()
120{
121 char *result = getenv(myName.ToCString());
122 if (result == NULL) myValue.Clear();
123 else myValue = result;
124 return myValue;
125}
126
127// ----------------------------------------------------------------------
128// Sets physically the environment variable
129// ----------------------------------------------------------------------
130
131void OSD_Environment::Build ()
132{
133 // Static buffer to hold definitions of new variables for the environment.
134 // Note that they need to be static since putenv does not make a copy
135 // of the string, but just adds its pointer to the environment.
136 static char **buffer = 0 ; // JPT:
137 static int Ibuffer = 0 ; // Tout ca pour putenv,getenv
138
139 // Use mutex to avoid concurrent access to the buffer
140 static Standard_Mutex theMutex;
141 Standard_Mutex::Sentry aSentry ( theMutex );
142
143 // check if such variable has already been created in the buffer
144 int index = -1, len = myName.Length();
145 for ( int i=0; i < Ibuffer; i++ ) {
146 if ( ! strncmp ( buffer[i], myName.ToCString(), len ) && buffer[i][len] == '=' ) {
147 index = i;
148 break;
149 }
150 }
151
152 // and either add a new entry, or remember the old entry for a while
153 char *old_value = 0;
154 if ( index >=0 ) {
155 old_value = buffer[index];
156 }
157 else {
158 // Allocation memoire. Surtout tout la heap!
159 index = Ibuffer++;
8413a813 160 char **aTmp;
161 aTmp = (char **) realloc ( buffer, Ibuffer * sizeof(char*) );
162 if (aTmp)
163 {
164 buffer = aTmp;
165 }
166 else
167 {
168 myError.SetValue(errno, Iam, "Memory realloc failure");
169 return;
170 }
7fd59977 171 }
172
173 // create a new entry in the buffer and add it to environment
174 buffer[index] = (char *) malloc ( len + myValue.Length() + 2 );
175 sprintf(buffer[index], "%s=%s", myName.ToCString(), myValue.ToCString());
176 putenv(buffer[index]);
177
178 // then (and only then!) free old entry, if existed
179 if ( old_value )
180 free ( old_value );
181
182 // check the result
183 char *result = getenv(myName.ToCString());
184 if (result == NULL)
185 myError.SetValue(errno, Iam, "Set Environment");
186}
187
188// ----------------------------------------------------------------------
189// Remove physically the environment variable
190// ----------------------------------------------------------------------
191
192void OSD_Environment::Remove ()
193{
194 myValue.Clear();
195 Build();
196}
197
198
199
200// ----------------------------------------------------------------------
201// ----------------------------------------------------------------------
202void OSD_Environment::Reset()
203{
204 myError.Reset();
205}
206
207// ----------------------------------------------------------------------
208// ----------------------------------------------------------------------
209Standard_Boolean OSD_Environment::Failed() const
210{
211 return myError.Failed();
212}
213
214// ----------------------------------------------------------------------
215// ----------------------------------------------------------------------
216void OSD_Environment::Perror()
217{
218 myError.Perror();
219}
220
221
222// ----------------------------------------------------------------------
223// ----------------------------------------------------------------------
224Standard_Integer OSD_Environment::Error() const
225{
226 return myError.Error();
227}
228
229#else
230
231//------------------------------------------------------------------------
232//------------------- WNT Sources of OSD_Environment --------------------
233//------------------------------------------------------------------------
234
235#define STRICT
ad03c234 236#include <windows.h>
237
7fd59977 238#include <OSD_Environment.hxx>
239
240#include <OSD_WNT.hxx>
241
1ce0716b 242#include <NCollection_DataMap.hxx>
8582eb08 243#include <NCollection_UtfString.hxx>
1ce0716b 244#include <Standard_Mutex.hxx>
8582eb08 245
1ce0716b 246#ifdef OCCT_UWP
247namespace
248{
249 // emulate global map of environment variables
250 static Standard_Mutex THE_ENV_LOCK;
251 static NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> THE_ENV_MAP;
252}
253#else
7fd59977 254static void __fastcall _set_error ( OSD_Error&, DWORD );
742cc8b0 255#endif
7fd59977 256
257OSD_Environment :: OSD_Environment () {
258
259} // end constructor ( 1 )
260
261OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name ) {
262
263 myName = Name;
264
265} // end constructor ( 2 )
266
267OSD_Environment :: OSD_Environment (
268 const TCollection_AsciiString& Name,
269 const TCollection_AsciiString& Value
270 ) {
271
272 myName = Name;
273 myValue = Value;
274
275} // end constructor ( 3 )
276
277void OSD_Environment :: SetValue ( const TCollection_AsciiString& Value ) {
278
279 myValue = Value;
280
281} // end OSD_Environment :: SetValue
282
8582eb08 283TCollection_AsciiString OSD_Environment::Value()
284{
285 myValue.Clear();
1ce0716b 286#ifdef OCCT_UWP
287 Standard_Mutex::Sentry aLock (THE_ENV_LOCK);
288 THE_ENV_MAP.Find (myName, myValue);
289#else
8582eb08 290 SetLastError (ERROR_SUCCESS);
291 wchar_t* anEnvVal = NULL;
292 NCollection_UtfWideString aNameWide (myName.ToCString());
293 DWORD aSize = GetEnvironmentVariableW (aNameWide.ToCString(), NULL, 0);
294 if ((aSize == 0 && GetLastError() != ERROR_SUCCESS)
295 || (anEnvVal = _wgetenv (aNameWide.ToCString())) == NULL)
296 {
297 _set_error (myError, ERROR_ENVVAR_NOT_FOUND);
298 return myValue;
299 }
7fd59977 300
8582eb08 301 NCollection_Utf8String aValue;
302 if (anEnvVal != NULL)
303 {
304 aValue.FromUnicode (anEnvVal);
305 }
306 else
307 {
308 aSize += 1; // NULL-terminator
309 wchar_t* aBuff = new wchar_t[aSize];
310 GetEnvironmentVariableW (aNameWide.ToCString(), aBuff, aSize);
311 aBuff[aSize - 1] = L'\0';
312 aValue.FromUnicode (aBuff);
313 delete[] aBuff;
314 Reset();
315 }
316 myValue = aValue.ToCString();
742cc8b0 317#endif
1ce0716b 318 return myValue;
8582eb08 319}
7fd59977 320
321void OSD_Environment :: SetName ( const TCollection_AsciiString& name ) {
322
323 myName = name;
324
325} // end OSD_Environment :: SetName
326
327TCollection_AsciiString OSD_Environment :: Name () const {
328
329 return myName;
330
331} // end OSD_Environment :: Name
332
8582eb08 333void OSD_Environment::Build()
334{
1ce0716b 335#ifdef OCCT_UWP
336 Standard_Mutex::Sentry aLock(THE_ENV_LOCK);
337 THE_ENV_MAP.Bind (myName, myValue);
338#else
8582eb08 339 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=" + myValue.ToCString();
340 _wputenv (aSetVariable.ToUtfWide().ToCString());
742cc8b0 341#endif
8582eb08 342}
7fd59977 343
8582eb08 344void OSD_Environment::Remove()
345{
1ce0716b 346#ifdef OCCT_UWP
347 Standard_Mutex::Sentry aLock(THE_ENV_LOCK);
348 THE_ENV_MAP.UnBind (myName);
349#else
8582eb08 350 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=";
351 _wputenv (aSetVariable.ToUtfWide().ToCString());
742cc8b0 352#endif
8582eb08 353}
7fd59977 354
355Standard_Boolean OSD_Environment :: Failed () const {
356
357 return myError.Failed ();
358
359} // end OSD_Environment :: Failed
360
361void OSD_Environment :: Reset () {
362
363 myError.Reset ();
364
365} // end OSD_Environment :: Reset
366
46802936 367void OSD_Environment :: Perror ()
368{
369 myError.Perror ();
7fd59977 370} // end OSD_Environment :: Perror
371
372Standard_Integer OSD_Environment :: Error () const {
373
374 return myError.Error ();
375
376} // end OSD_Environment :: Error
377
742cc8b0 378#ifndef OCCT_UWP
ad03c234 379static void __fastcall _set_error (OSD_Error& theErr, DWORD theCode)
380{
381 wchar_t aBuffer[2048];
382 const DWORD anErrCode = theCode != 0 ? theCode : GetLastError();
383 if (!FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
384 0, anErrCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
385 aBuffer, 2048, NULL))
386 {
387 theErr.SetValue (anErrCode, OSD_WEnvironment, TCollection_AsciiString ("error code ") + (Standard_Integer)anErrCode);
388 SetLastError (anErrCode);
389 }
390 else
391 {
392 theErr.SetValue (anErrCode, OSD_WEnvironment, TCollection_AsciiString (aBuffer));
393 }
394}
742cc8b0 395#endif
7fd59977 396
397#endif