Mercurial > projects > ldc
comparison tango/tango/sys/Environment.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2007 Tango. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Feb 2007: Initial release | |
8 | |
9 author: Deewiant, Maxter, Gregor, Kris | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.sys.Environment; | |
14 | |
15 private import tango.sys.Common; | |
16 | |
17 private import tango.io.FilePath, | |
18 tango.io.FileConst, | |
19 tango.io.FileSystem; | |
20 | |
21 private import tango.core.Exception; | |
22 | |
23 private import Text = tango.text.Util; | |
24 | |
25 /******************************************************************************* | |
26 | |
27 *******************************************************************************/ | |
28 | |
29 version (Windows) | |
30 { | |
31 private import tango.text.convert.Utf; | |
32 | |
33 pragma (lib, "kernel32.lib"); | |
34 | |
35 extern (Windows) | |
36 { | |
37 private void* GetEnvironmentStringsW(); | |
38 private bool FreeEnvironmentStringsW(wchar**); | |
39 } | |
40 extern (Windows) | |
41 { | |
42 private int SetEnvironmentVariableW(wchar*, wchar*); | |
43 private uint GetEnvironmentVariableW(wchar*, wchar*, uint); | |
44 private const int ERROR_ENVVAR_NOT_FOUND = 203; | |
45 } | |
46 } | |
47 else | |
48 { | |
49 private extern (C) extern char** environ; | |
50 | |
51 import tango.stdc.posix.stdlib; | |
52 import tango.stdc.string; | |
53 } | |
54 | |
55 | |
56 /******************************************************************************* | |
57 | |
58 Exposes the system Environment settings, along with some handy | |
59 utilities | |
60 | |
61 *******************************************************************************/ | |
62 | |
63 struct Environment | |
64 { | |
65 /*********************************************************************** | |
66 | |
67 Returns the full path location of the provided executable | |
68 file, rifling through the PATH as necessary. | |
69 | |
70 Returns null if the provided filename was not found | |
71 | |
72 ***********************************************************************/ | |
73 | |
74 static FilePath exePath (char[] file) | |
75 { | |
76 auto bin = new FilePath (file); | |
77 | |
78 // on Windows, this is a .exe | |
79 version (Windows) | |
80 if (bin.ext.length is 0) | |
81 bin.append (".exe"); | |
82 | |
83 // is this a directory? Potentially make it absolute | |
84 if (bin.isChild) | |
85 return FileSystem.toAbsolute (bin); | |
86 | |
87 // is it in cwd? | |
88 version (Windows) | |
89 if (bin.path(FileSystem.getDirectory).exists) | |
90 return bin; | |
91 | |
92 // rifle through the path | |
93 foreach (pe; Text.patterns (get("PATH"), FileConst.SystemPathString)) | |
94 if (bin.path(pe).exists) | |
95 version (Windows) | |
96 return bin; | |
97 else | |
98 { | |
99 stat_t stats; | |
100 stat(bin.cString.ptr, &stats); | |
101 if (stats.st_mode & 0100) | |
102 return bin; | |
103 } | |
104 return null; | |
105 } | |
106 | |
107 | |
108 version (Win32) | |
109 { | |
110 /************************************************************** | |
111 | |
112 Returns the provided 'def' value if the variable | |
113 does not exist | |
114 | |
115 **************************************************************/ | |
116 | |
117 static char[] get (char[] variable, char[] def = null) | |
118 { | |
119 wchar[] var = toString16(variable) ~ "\0"; | |
120 | |
121 uint size = GetEnvironmentVariableW(var.ptr, cast(wchar*)null, 0); | |
122 if (size is 0) | |
123 { | |
124 if (SysError.lastCode is ERROR_ENVVAR_NOT_FOUND) | |
125 return def; | |
126 else | |
127 throw new PlatformException (SysError.lastMsg); | |
128 } | |
129 | |
130 auto buffer = new wchar[size]; | |
131 size = GetEnvironmentVariableW(var.ptr, buffer.ptr, size); | |
132 if (size is 0) | |
133 throw new PlatformException (SysError.lastMsg); | |
134 | |
135 return toString (buffer[0 .. size]); | |
136 } | |
137 | |
138 /************************************************************** | |
139 | |
140 clears the variable if value is null or empty | |
141 | |
142 **************************************************************/ | |
143 | |
144 static void set (char[] variable, char[] value = null) | |
145 { | |
146 wchar * var, val; | |
147 | |
148 var = (toString16 (variable) ~ "\0").ptr; | |
149 | |
150 if (value.length > 0) | |
151 val = (toString16 (value) ~ "\0").ptr; | |
152 | |
153 if (! SetEnvironmentVariableW(var, val)) | |
154 throw new PlatformException (SysError.lastMsg); | |
155 } | |
156 | |
157 /************************************************************** | |
158 | |
159 **************************************************************/ | |
160 | |
161 static char[][char[]] get () | |
162 { | |
163 char[][char[]] arr; | |
164 | |
165 wchar[] key = new wchar[20], | |
166 value = new wchar[40]; | |
167 | |
168 wchar** env = cast(wchar**) GetEnvironmentStringsW(); | |
169 scope (exit) | |
170 FreeEnvironmentStringsW (env); | |
171 | |
172 for (wchar* str = cast(wchar*) env; *str; ++str) | |
173 { | |
174 size_t k = 0, v = 0; | |
175 | |
176 while (*str != '=') | |
177 { | |
178 key[k++] = *str++; | |
179 | |
180 if (k is key.length) | |
181 key.length = 2 * key.length; | |
182 } | |
183 | |
184 ++str; | |
185 | |
186 while (*str) | |
187 { | |
188 value [v++] = *str++; | |
189 | |
190 if (v is value.length) | |
191 value.length = 2 * value.length; | |
192 } | |
193 | |
194 arr [toString(key[0 .. k])] = toString(value[0 .. v]); | |
195 } | |
196 | |
197 return arr; | |
198 } | |
199 } | |
200 else // POSIX | |
201 { | |
202 /************************************************************** | |
203 | |
204 Returns the provided 'def' value if the variable | |
205 does not exist | |
206 | |
207 **************************************************************/ | |
208 | |
209 static char[] get (char[] variable, char[] def = null) | |
210 { | |
211 char* ptr = getenv (variable.ptr); | |
212 | |
213 if (ptr is null) | |
214 return def; | |
215 | |
216 return ptr[0 .. strlen(ptr)].dup; | |
217 } | |
218 | |
219 /************************************************************** | |
220 | |
221 clears the variable, if value is null or empty | |
222 | |
223 **************************************************************/ | |
224 | |
225 static void set (char[] variable, char[] value = null) | |
226 { | |
227 int result; | |
228 | |
229 if (value.length is 0) | |
230 unsetenv ((variable ~ '\0').ptr); | |
231 else | |
232 result = setenv ((variable ~ '\0').ptr, (value ~ '\0').ptr, 1); | |
233 | |
234 if (result != 0) | |
235 throw new PlatformException (SysError.lastMsg); | |
236 } | |
237 | |
238 /************************************************************** | |
239 | |
240 **************************************************************/ | |
241 | |
242 static char[][char[]] get () | |
243 { | |
244 char[][char[]] arr; | |
245 | |
246 for (char** p = environ; *p; ++p) | |
247 { | |
248 size_t k = 0; | |
249 char* str = *p; | |
250 | |
251 while (*str++ != '=') | |
252 ++k; | |
253 char[] key = (*p)[0..k]; | |
254 | |
255 k = 0; | |
256 char* val = str; | |
257 while (*str++) | |
258 ++k; | |
259 arr[key] = val[0 .. k]; | |
260 } | |
261 | |
262 return arr; | |
263 } | |
264 } | |
265 } | |
266 | |
267 debug (Environment) | |
268 { | |
269 import tango.io.Console; | |
270 | |
271 | |
272 void main(char[][] args) | |
273 { | |
274 const char[] VAR = "TESTENVVAR"; | |
275 const char[] VAL1 = "VAL1"; | |
276 const char[] VAL2 = "VAL2"; | |
277 | |
278 assert(Environment.get(VAR) is null); | |
279 | |
280 Environment.set(VAR, VAL1); | |
281 assert(Environment.get(VAR) == VAL1); | |
282 | |
283 Environment.set(VAR, VAL2); | |
284 assert(Environment.get(VAR) == VAL2); | |
285 | |
286 Environment.set(VAR, null); | |
287 assert(Environment.get(VAR) is null); | |
288 | |
289 Environment.set(VAR, VAL1); | |
290 Environment.set(VAR, ""); | |
291 | |
292 assert(Environment.get(VAR) is null); | |
293 | |
294 foreach (key, value; Environment.get) | |
295 Cout (key) ("=") (value).newline; | |
296 | |
297 if (args.length > 0) | |
298 { | |
299 auto p = Environment.exePath (args[0]); | |
300 Cout (p).newline; | |
301 } | |
302 | |
303 if (args.length > 1) | |
304 { | |
305 if (auto p = Environment.exePath (args[1])) | |
306 Cout (p).newline; | |
307 } | |
308 } | |
309 } | |
310 |