Home | History | Annotate | Download | only in stdlib
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Lesser General Public
      7     License as published by the Free Software Foundation; either
      8     version 2.1 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Lesser General Public License for more details.
     14 
     15     You should have received a copy of the GNU Lesser General Public
     16     License along with this library; if not, write to the Free Software
     17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #include "SDL_stdinc.h"
     25 
     26 #ifndef HAVE_GETENV
     27 
     28 #if defined(__WIN32__) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
     29 
     30 #define WIN32_LEAN_AND_MEAN
     31 #include <windows.h>
     32 
     33 /* Note this isn't thread-safe! */
     34 
     35 static char *SDL_envmem = NULL;	/* Ugh, memory leak */
     36 static size_t SDL_envmemlen = 0;
     37 
     38 /* Put a variable of the form "name=value" into the environment */
     39 int SDL_putenv(const char *variable)
     40 {
     41 	size_t bufferlen;
     42 	char *value;
     43 	const char *sep;
     44 
     45 	sep = SDL_strchr(variable, '=');
     46 	if ( sep == NULL ) {
     47 		return -1;
     48 	}
     49 	bufferlen = SDL_strlen(variable)+1;
     50 	if ( bufferlen > SDL_envmemlen ) {
     51 		char *newmem = (char *)SDL_realloc(SDL_envmem, bufferlen);
     52 		if ( newmem == NULL ) {
     53 			return -1;
     54 		}
     55 		SDL_envmem = newmem;
     56 		SDL_envmemlen = bufferlen;
     57 	}
     58 	SDL_strlcpy(SDL_envmem, variable, bufferlen);
     59 	value = SDL_envmem + (sep - variable);
     60 	*value++ = '\0';
     61 	if ( !SetEnvironmentVariable(SDL_envmem, *value ? value : NULL) ) {
     62 		return -1;
     63 	}
     64 	return 0;
     65 }
     66 
     67 /* Retrieve a variable named "name" from the environment */
     68 char *SDL_getenv(const char *name)
     69 {
     70 	size_t bufferlen;
     71 
     72 	bufferlen = GetEnvironmentVariable(name, SDL_envmem, (DWORD)SDL_envmemlen);
     73 	if ( bufferlen == 0 ) {
     74 		return NULL;
     75 	}
     76 	if ( bufferlen > SDL_envmemlen ) {
     77 		char *newmem = (char *)SDL_realloc(SDL_envmem, bufferlen);
     78 		if ( newmem == NULL ) {
     79 			return NULL;
     80 		}
     81 		SDL_envmem = newmem;
     82 		SDL_envmemlen = bufferlen;
     83 		GetEnvironmentVariable(name, SDL_envmem, (DWORD)SDL_envmemlen);
     84 	}
     85 	return SDL_envmem;
     86 }
     87 
     88 #else /* roll our own */
     89 
     90 static char **SDL_env = (char **)0;
     91 
     92 /* Put a variable of the form "name=value" into the environment */
     93 int SDL_putenv(const char *variable)
     94 {
     95 	const char *name, *value;
     96 	int added;
     97 	int len, i;
     98 	char **new_env;
     99 	char *new_variable;
    100 
    101 	/* A little error checking */
    102 	if ( ! variable ) {
    103 		return(-1);
    104 	}
    105 	name = variable;
    106 	for ( value=variable; *value && (*value != '='); ++value ) {
    107 		/* Keep looking for '=' */ ;
    108 	}
    109 	if ( *value ) {
    110 		++value;
    111 	} else {
    112 		return(-1);
    113 	}
    114 
    115 	/* Allocate memory for the variable */
    116 	new_variable = SDL_strdup(variable);
    117 	if ( ! new_variable ) {
    118 		return(-1);
    119 	}
    120 
    121 	/* Actually put it into the environment */
    122 	added = 0;
    123 	i = 0;
    124 	if ( SDL_env ) {
    125 		/* Check to see if it's already there... */
    126 		len = (value - name);
    127 		for ( ; SDL_env[i]; ++i ) {
    128 			if ( SDL_strncmp(SDL_env[i], name, len) == 0 ) {
    129 				break;
    130 			}
    131 		}
    132 		/* If we found it, just replace the entry */
    133 		if ( SDL_env[i] ) {
    134 			SDL_free(SDL_env[i]);
    135 			SDL_env[i] = new_variable;
    136 			added = 1;
    137 		}
    138 	}
    139 
    140 	/* Didn't find it in the environment, expand and add */
    141 	if ( ! added ) {
    142 		new_env = SDL_realloc(SDL_env, (i+2)*sizeof(char *));
    143 		if ( new_env ) {
    144 			SDL_env = new_env;
    145 			SDL_env[i++] = new_variable;
    146 			SDL_env[i++] = (char *)0;
    147 			added = 1;
    148 		} else {
    149 			SDL_free(new_variable);
    150 		}
    151 	}
    152 	return (added ? 0 : -1);
    153 }
    154 
    155 /* Retrieve a variable named "name" from the environment */
    156 char *SDL_getenv(const char *name)
    157 {
    158 	int len, i;
    159 	char *value;
    160 
    161 	value = (char *)0;
    162 	if ( SDL_env ) {
    163 		len = SDL_strlen(name);
    164 		for ( i=0; SDL_env[i] && !value; ++i ) {
    165 			if ( (SDL_strncmp(SDL_env[i], name, len) == 0) &&
    166 			     (SDL_env[i][len] == '=') ) {
    167 				value = &SDL_env[i][len+1];
    168 			}
    169 		}
    170 	}
    171 	return value;
    172 }
    173 
    174 #endif /* __WIN32__ */
    175 
    176 #endif /* !HAVE_GETENV */
    177 
    178 #ifdef TEST_MAIN
    179 #include <stdio.h>
    180 
    181 int main(int argc, char *argv[])
    182 {
    183 	char *value;
    184 
    185 	printf("Checking for non-existent variable... ");
    186 	fflush(stdout);
    187 	if ( ! SDL_getenv("EXISTS") ) {
    188 		printf("okay\n");
    189 	} else {
    190 		printf("failed\n");
    191 	}
    192 	printf("Setting FIRST=VALUE1 in the environment... ");
    193 	fflush(stdout);
    194 	if ( SDL_putenv("FIRST=VALUE1") == 0 ) {
    195 		printf("okay\n");
    196 	} else {
    197 		printf("failed\n");
    198 	}
    199 	printf("Getting FIRST from the environment... ");
    200 	fflush(stdout);
    201 	value = SDL_getenv("FIRST");
    202 	if ( value && (SDL_strcmp(value, "VALUE1") == 0) ) {
    203 		printf("okay\n");
    204 	} else {
    205 		printf("failed\n");
    206 	}
    207 	printf("Setting SECOND=VALUE2 in the environment... ");
    208 	fflush(stdout);
    209 	if ( SDL_putenv("SECOND=VALUE2") == 0 ) {
    210 		printf("okay\n");
    211 	} else {
    212 		printf("failed\n");
    213 	}
    214 	printf("Getting SECOND from the environment... ");
    215 	fflush(stdout);
    216 	value = SDL_getenv("SECOND");
    217 	if ( value && (SDL_strcmp(value, "VALUE2") == 0) ) {
    218 		printf("okay\n");
    219 	} else {
    220 		printf("failed\n");
    221 	}
    222 	printf("Setting FIRST=NOVALUE in the environment... ");
    223 	fflush(stdout);
    224 	if ( SDL_putenv("FIRST=NOVALUE") == 0 ) {
    225 		printf("okay\n");
    226 	} else {
    227 		printf("failed\n");
    228 	}
    229 	printf("Getting FIRST from the environment... ");
    230 	fflush(stdout);
    231 	value = SDL_getenv("FIRST");
    232 	if ( value && (SDL_strcmp(value, "NOVALUE") == 0) ) {
    233 		printf("okay\n");
    234 	} else {
    235 		printf("failed\n");
    236 	}
    237 	printf("Checking for non-existent variable... ");
    238 	fflush(stdout);
    239 	if ( ! SDL_getenv("EXISTS") ) {
    240 		printf("okay\n");
    241 	} else {
    242 		printf("failed\n");
    243 	}
    244 	return(0);
    245 }
    246 #endif /* TEST_MAIN */
    247 
    248