fdc9638f20b62db7ec63d9af7440d9763e0eeb22
[occt.git] / src / OSD / OSD_Environment.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _WIN32
16
17
18 #include <OSD_Environment.hxx>
19 #include <OSD_OSDError.hxx>
20 #include <OSD_WhoAmI.hxx>
21 #include <Standard_ConstructionError.hxx>
22 #include <Standard_Failure.hxx>
23 #include <Standard_Mutex.hxx>
24 #include <Standard_NullObject.hxx>
25 #include <TCollection_AsciiString.hxx>
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 static 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
44 OSD_Environment::OSD_Environment()
45 {
46 }
47
48
49 // ----------------------------------------------------------------------
50 // Constructor
51 // ----------------------------------------------------------------------
52
53 OSD_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
67 OSD_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
85 TCollection_AsciiString OSD_Environment::Name () const
86 {
87  return myName;
88 }
89
90 // ----------------------------------------------------------------------
91 // Set new value for environment variable
92 // ----------------------------------------------------------------------
93
94 void 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
107 void 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
119 TCollection_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
131 void 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++;
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     }
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
192 void OSD_Environment::Remove ()
193 {
194   myValue.Clear();
195   Build();
196 }
197
198
199
200 // ----------------------------------------------------------------------
201 // ----------------------------------------------------------------------
202 void OSD_Environment::Reset()
203 {
204   myError.Reset();
205 }
206
207 // ----------------------------------------------------------------------
208 // ----------------------------------------------------------------------
209 Standard_Boolean OSD_Environment::Failed() const
210 {
211   return myError.Failed();
212 }
213
214 // ----------------------------------------------------------------------
215 // ----------------------------------------------------------------------
216 void OSD_Environment::Perror() 
217 {
218   myError.Perror();
219 }
220
221
222 // ----------------------------------------------------------------------
223 // ----------------------------------------------------------------------
224 Standard_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
236 #include <OSD_Environment.hxx>
237
238 #include <OSD_WNT.hxx>
239
240 #include <windows.h>
241
242 #pragma warning( disable : 4700 )
243
244 static void __fastcall _set_error ( OSD_Error&, DWORD );
245
246 OSD_Environment :: OSD_Environment () {
247
248 }  // end constructor ( 1 )
249
250 OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name ) {
251
252  myName = Name;
253
254 }  // end constructor ( 2 )
255
256 OSD_Environment :: OSD_Environment (
257                     const TCollection_AsciiString& Name,
258                     const TCollection_AsciiString& Value
259                    ) {
260
261  myName  = Name;
262  myValue = Value;
263
264 }  // end constructor ( 3 )
265
266 void OSD_Environment :: SetValue ( const TCollection_AsciiString& Value ) {
267
268  myValue = Value;
269
270 }  // end OSD_Environment :: SetValue
271
272 TCollection_AsciiString OSD_Environment :: Value () {
273
274  Standard_PCharacter pBuff=0;
275  DWORD            dwSize = 0;
276  char*            envVal = NULL;
277
278  myValue.Clear ();
279
280  SetLastError ( ERROR_SUCCESS );
281  dwSize = GetEnvironmentVariable (  myName.ToCString (), pBuff, dwSize  );
282
283  if (    ( dwSize == 0 && GetLastError () != ERROR_SUCCESS ) ||
284          (  envVal = getenv (  myName.ToCString ()  )  ) == NULL
285  )
286
287   _set_error ( myError, ERROR_ENVVAR_NOT_FOUND );
288
289  else if ( envVal != NULL )
290
291   myValue = envVal;
292
293  else {
294
295   ++dwSize; 
296   pBuff = new Standard_Character[ dwSize ];
297   GetEnvironmentVariable (  (char *)myName.ToCString (), pBuff, dwSize  );
298   myValue = pBuff;
299   delete [] pBuff;
300   Reset ();
301  
302  }  // end else
303
304  return myValue;
305
306 }  // end OSD_Environment :: Value
307
308 void OSD_Environment :: SetName ( const TCollection_AsciiString& name ) {
309
310  myName = name;
311
312 }  // end OSD_Environment :: SetName
313
314 TCollection_AsciiString OSD_Environment :: Name () const {
315
316  return myName;
317
318 }  // end OSD_Environment :: Name
319
320 void OSD_Environment :: Build () {
321
322  TCollection_AsciiString str;
323
324  str = myName + TEXT( "=" ) + myValue;
325
326  putenv (  str.ToCString ()  );
327
328 }  // end OSD_Environment :: Build
329
330 void OSD_Environment :: Remove () {
331
332  TCollection_AsciiString str;
333
334  str = myName + TEXT( "=" );
335
336  putenv (  str.ToCString ()  );
337
338 }  // end OSD_Environment :: Remove
339
340 Standard_Boolean OSD_Environment :: Failed () const {
341
342  return myError.Failed ();
343
344 }  // end OSD_Environment :: Failed
345
346 void OSD_Environment :: Reset () {
347
348  myError.Reset ();
349
350 }  // end OSD_Environment :: Reset
351
352 void OSD_Environment :: Perror () {
353
354  if (  ErrorPrefix ()  )
355
356   (  *ErrorStream ()  ) << TEXT( '\'' ) << myName.ToCString () << TEXT( "' - " );
357
358  myError.Perror ();
359
360 }  // end OSD_Environment :: Perror
361
362 Standard_Integer OSD_Environment :: Error () const {
363
364  return myError.Error ();
365
366 }  // end OSD_Environment :: Error
367
368 static void __fastcall _set_error ( OSD_Error& err, DWORD code ) {
369
370  DWORD              errCode;
371  Standard_Character buffer[ 2048 ];
372
373  errCode = code ? code : GetLastError ();
374
375  if (  !FormatMessage (
376          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
377          0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
378          buffer, 2048, NULL
379         )
380  ) {
381  
382   sprintf ( buffer, "error code %d", (Standard_Integer)errCode );
383   SetLastError ( errCode );
384
385  }  // end if
386
387  err.SetValue ( errCode, OSD_WEnvironment, buffer );
388
389 }  // end _set_error
390
391 #endif