View mode: basic / threaded / horizontal-split · Log in · Help
June 12, 2006
Code to get all environment variables
Something like this should really be in Phobos, and unless it's already there, Ares.

I figured I'd post what I coded to accomplish this task. It should work in
Windows and any Posix platform - I tested it only on Windows XP and Cygwin,
though, but it ought to be alright.

The Windows code uses the ASCII, not UTF-16, versions of the functions, since
I'm not comfortable messing around with different encodings - I'm not sure
whether it would be smarter to make the Posix version convert ASCII to wchars or
the Windows code to convert UTF-16 to chars.

I was never good with pointer twiddling, so I couldn't figure out a way to use
the same code for both versions. Feel free to do whatever you want with it, I
release it in the public domain.

--

version (Windows) {
	pragma (lib, "kernel32");

	extern (Windows) {
		void * GetEnvironmentStringsA();
		bool   FreeEnvironmentStringsA(char**);
	}

	char[][char[]] environment() {
		char ** env = cast(char**)GetEnvironmentStringsA();
		scope (exit) FreeEnvironmentStringsA(env);

		char[][char[]] arr;

		for (char * str = cast(char*)env; *str; ++str) {
			char[] key   = new char[20],
			       value = new char[40];

			size_t i;

			while (*str != '=') {
				key[i++] = *str++;

				if (i == key.length)
					key.length = 2 * key.length;
			}
			key.length = i;

			i = 0;
			++str;

			while (*str) {
				value[i++] = *str++;

				if (i == value.length)
					value.length = 2 * value.length;
			}
			value.length = i;

			arr[key] = value;
		}

		return arr;
	}
} else {
	pragma (msg, "If this is not a Posix-compliant platform, trying to access
environment\nvariables will probably cause an access violation and thereby a
crash.");

	extern (C) extern char ** environ;

	char[][char[]] environment() {
		char[][char[]] arr;

		for (char ** p = environ; *p; ++p) {
			char[] key   = new char[20],
			       value = new char[40];

			size_t i;
			char * str = *p;

			while (*str != '=') {
				key[i++] = *str++;

				if (i == key.length)
					key.length = 2 * key.length;
			}
			key.length = i;

			i = 0;
			++str;

			while (*str) {
				value[i++] = *str++;

				if (i == value.length)
					value.length = 2 * value.length;
			}
			value.length = i;

			arr[key] = value;
		}

		return arr;
	}
}
June 13, 2006
Re: Code to get all environment variables
Deewiant schrieb am 2006-06-12:

<snip>

> The Windows code uses the ASCII, not UTF-16, versions of the functions, since
> I'm not comfortable messing around with different encodings

I'm not a MSWindows native..

Are you sure that GetEnvironmentStringsA and FreeEnvironmentStringsA use ASCII?
I'd expect them to use locale and/or installation dependent ANSI encoding.

> whether it would be smarter to make the Posix version convert ASCII to wchars or
> the Windows code to convert UTF-16 to chars.

Unless there any strong reasons - like buggy implementations in some MSWindows
versions - I'd opt for the UTF-16 to UTF-8 conversion.

Thoms
June 14, 2006
Re: Code to get all environment variables
Thomas Kuehne wrote:
> Are you sure that GetEnvironmentStringsA and FreeEnvironmentStringsA use ASCII?
> I'd expect them to use locale and/or installation dependent ANSI encoding.
> 
> Unless there any strong reasons - like buggy implementations in some MSWindows
> versions - I'd opt for the UTF-16 to UTF-8 conversion.
> 
> Thoms
> 

It seems you're right, they do. *sigh*

Hence, replace the *A functions with *W, change "char" to "wchar" in everything
but the declaration of "arr", and use toUTF8() in the last line of the loop,
like so:

arr[toUTF8(key)] = toUTF8(value);

And thus, of course, import std.utf.

The only problem now is that Windows 95/98/ME require the "Microsoft Layer for
Unicode" - some sort of OS patch, I gather - for the UTF-16 versions of the
functions to work.

I'm not familiar enough with the Windows SDK to know whether there's an easy way
to convert from "whatever encoding the ANSI versions of the functions return" to
the UTF-16 form easily, so my suggestion to users of those OSs is to just go and
update their systems.
Top | Discussion index | About this forum | D home