Thread overview
Code to get all environment variables
Jun 12, 2006
Deewiant
Jun 13, 2006
Thomas Kuehne
Jun 14, 2006
Deewiant
June 12, 2006
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
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
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.