SDL-1.2.14
[sdl_omap.git] / src / stdlib / SDL_getenv.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 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@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