0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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 )
9775fa61 57 throw Standard_ConstructionError("OSD_Environment::OSD_Environment: bad argument");
7fd59977 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 )
9775fa61 74 throw Standard_ConstructionError("OSD_Environment::OSD_Environment: bad argument");
7fd59977 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 )
9775fa61 98 throw Standard_ConstructionError("OSD_Environment::SetName: bad argument");
7fd59977 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)
9775fa61 110 throw Standard_ConstructionError("OSD_Environment::Change: bad argument");
7fd59977 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
ad03c234 235#include <windows.h>
236
7fd59977 237#include <OSD_Environment.hxx>
238
1ce0716b 239#include <NCollection_DataMap.hxx>
8582eb08 240#include <NCollection_UtfString.hxx>
1ce0716b 241#include <Standard_Mutex.hxx>
8582eb08 242
1ce0716b 243#ifdef OCCT_UWP
244namespace
245{
246 // emulate global map of environment variables
247 static Standard_Mutex THE_ENV_LOCK;
248 static NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> THE_ENV_MAP;
249}
250#else
7fd59977 251static void __fastcall _set_error ( OSD_Error&, DWORD );
742cc8b0 252#endif
7fd59977 253
254OSD_Environment :: OSD_Environment () {
255
256} // end constructor ( 1 )
257
258OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name ) {
259
260 myName = Name;
261
262} // end constructor ( 2 )
263
264OSD_Environment :: OSD_Environment (
265 const TCollection_AsciiString& Name,
266 const TCollection_AsciiString& Value
267 ) {
268
269 myName = Name;
270 myValue = Value;
271
272} // end constructor ( 3 )
273
274void OSD_Environment :: SetValue ( const TCollection_AsciiString& Value ) {
275
276 myValue = Value;
277
278} // end OSD_Environment :: SetValue
279
8582eb08 280TCollection_AsciiString OSD_Environment::Value()
281{
282 myValue.Clear();
1ce0716b 283#ifdef OCCT_UWP
284 Standard_Mutex::Sentry aLock (THE_ENV_LOCK);
285 THE_ENV_MAP.Find (myName, myValue);
286#else
e87d0237 287
288 // msvc C-runtime (_wputenv()) puts variable using WinAPI internally (calls SetEnvironmentVariableW())
289 // and also caches its value in its own map,
5e6e5914 290 // so that _wgetenv() ignores WinAPI and retrieves variable from this cache.
e87d0237 291 //
292 // Using _wgetenv() might lead to awkward results in context when several C-runtimes are used
293 // at once within application or WinAPI is used directly for setting environment variable.
294 //
295 // Using _wputenv() + GetEnvironmentVariableW() pair should provide most robust behavior in tricky scenarios.
296 // So that _wgetenv() users will retrieve proper value set by OSD_Environment if used C-runtime library is the same as used by OCCT,
297 // and OSD_Environment will retreieve most up-to-date value of environment variable nevertheless C-runtime version used (or not used at all) for setting value externally,
298 // considering msvc C-runtime implementation details.
8582eb08 299 SetLastError (ERROR_SUCCESS);
8582eb08 300 NCollection_UtfWideString aNameWide (myName.ToCString());
301 DWORD aSize = GetEnvironmentVariableW (aNameWide.ToCString(), NULL, 0);
e87d0237 302 if (aSize == 0 && GetLastError() != ERROR_SUCCESS)
8582eb08 303 {
304 _set_error (myError, ERROR_ENVVAR_NOT_FOUND);
305 return myValue;
306 }
7fd59977 307
8582eb08 308 NCollection_Utf8String aValue;
e87d0237 309 aSize += 1; // NULL-terminator
310 wchar_t* aBuff = new wchar_t[aSize];
311 GetEnvironmentVariableW (aNameWide.ToCString(), aBuff, aSize);
312 aBuff[aSize - 1] = L'\0';
313 aValue.FromUnicode (aBuff);
314 delete[] aBuff;
315 Reset();
316
8582eb08 317 myValue = aValue.ToCString();
742cc8b0 318#endif
1ce0716b 319 return myValue;
8582eb08 320}
7fd59977 321
322void OSD_Environment :: SetName ( const TCollection_AsciiString& name ) {
323
324 myName = name;
325
326} // end OSD_Environment :: SetName
327
328TCollection_AsciiString OSD_Environment :: Name () const {
329
330 return myName;
331
332} // end OSD_Environment :: Name
333
8582eb08 334void OSD_Environment::Build()
335{
1ce0716b 336#ifdef OCCT_UWP
337 Standard_Mutex::Sentry aLock(THE_ENV_LOCK);
338 THE_ENV_MAP.Bind (myName, myValue);
339#else
8582eb08 340 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=" + myValue.ToCString();
341 _wputenv (aSetVariable.ToUtfWide().ToCString());
742cc8b0 342#endif
8582eb08 343}
7fd59977 344
8582eb08 345void OSD_Environment::Remove()
346{
1ce0716b 347#ifdef OCCT_UWP
348 Standard_Mutex::Sentry aLock(THE_ENV_LOCK);
349 THE_ENV_MAP.UnBind (myName);
350#else
8582eb08 351 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=";
352 _wputenv (aSetVariable.ToUtfWide().ToCString());
742cc8b0 353#endif
8582eb08 354}
7fd59977 355
356Standard_Boolean OSD_Environment :: Failed () const {
357
358 return myError.Failed ();
359
360} // end OSD_Environment :: Failed
361
362void OSD_Environment :: Reset () {
363
364 myError.Reset ();
365
366} // end OSD_Environment :: Reset
367
46802936 368void OSD_Environment :: Perror ()
369{
370 myError.Perror ();
7fd59977 371} // end OSD_Environment :: Perror
372
373Standard_Integer OSD_Environment :: Error () const {
374
375 return myError.Error ();
376
377} // end OSD_Environment :: Error
378
742cc8b0 379#ifndef OCCT_UWP
ad03c234 380static void __fastcall _set_error (OSD_Error& theErr, DWORD theCode)
381{
382 wchar_t aBuffer[2048];
383 const DWORD anErrCode = theCode != 0 ? theCode : GetLastError();
384 if (!FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
385 0, anErrCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
386 aBuffer, 2048, NULL))
387 {
388 theErr.SetValue (anErrCode, OSD_WEnvironment, TCollection_AsciiString ("error code ") + (Standard_Integer)anErrCode);
389 SetLastError (anErrCode);
390 }
391 else
392 {
393 theErr.SetValue (anErrCode, OSD_WEnvironment, TCollection_AsciiString (aBuffer));
394 }
395}
742cc8b0 396#endif
7fd59977 397
398#endif