src/stdlib/SDL_getenv.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 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)
    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
    40 SDL_putenv(const char *variable)
    41 {
    42     size_t bufferlen;
    43     char *value;
    44     const char *sep;
    45 
    46     sep = SDL_strchr(variable, '=');
    47     if (sep == NULL) {
    48         return -1;
    49     }
    50     bufferlen = SDL_strlen(variable) + 1;
    51     if (bufferlen > SDL_envmemlen) {
    52         char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen);
    53         if (newmem == NULL) {
    54             return -1;
    55         }
    56         SDL_envmem = newmem;
    57         SDL_envmemlen = bufferlen;
    58     }
    59     SDL_strlcpy(SDL_envmem, variable, bufferlen);
    60     value = SDL_envmem + (sep - variable);
    61     *value++ = '\0';
    62     if (!SetEnvironmentVariable(SDL_envmem, *value ? value : NULL)) {
    63         return -1;
    64     }
    65     return 0;
    66 }
    67 
    68 /* Retrieve a variable named "name" from the environment */
    69 char *
    70 SDL_getenv(const char *name)
    71 {
    72     size_t bufferlen;
    73 
    74     bufferlen =
    75         GetEnvironmentVariable(name, SDL_envmem, (DWORD) SDL_envmemlen);
    76     if (bufferlen == 0) {
    77         return NULL;
    78     }
    79     if (bufferlen > SDL_envmemlen) {
    80         char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen);
    81         if (newmem == NULL) {
    82             return NULL;
    83         }
    84         SDL_envmem = newmem;
    85         SDL_envmemlen = bufferlen;
    86         GetEnvironmentVariable(name, SDL_envmem, (DWORD) SDL_envmemlen);
    87     }
    88     return SDL_envmem;
    89 }
    90 
    91 #else /* roll our own */
    92 
    93 static char **SDL_env = (char **) 0;
    94 
    95 /* Put a variable of the form "name=value" into the environment */
    96 int
    97 SDL_putenv(const char *variable)
    98 {
    99     const char *name, *value;
   100     int added;
   101     int len, i;
   102     char **new_env;
   103     char *new_variable;
   104 
   105     /* A little error checking */
   106     if (!variable) {
   107         return (-1);
   108     }
   109     name = variable;
   110     for (value = variable; *value && (*value != '='); ++value) {
   111         /* Keep looking for '=' */ ;
   112     }
   113     if (*value) {
   114         ++value;
   115     } else {
   116         return (-1);
   117     }
   118 
   119     /* Allocate memory for the variable */
   120     new_variable = SDL_strdup(variable);
   121     if (!new_variable) {
   122         return (-1);
   123     }
   124 
   125     /* Actually put it into the environment */
   126     added = 0;
   127     i = 0;
   128     if (SDL_env) {
   129         /* Check to see if it's already there... */
   130         len = (value - name);
   131         for (; SDL_env[i]; ++i) {
   132             if (SDL_strncmp(SDL_env[i], name, len) == 0) {
   133                 break;
   134             }
   135         }
   136         /* If we found it, just replace the entry */
   137         if (SDL_env[i]) {
   138             SDL_free(SDL_env[i]);
   139             SDL_env[i] = new_variable;
   140             added = 1;
   141         }
   142     }
   143 
   144     /* Didn't find it in the environment, expand and add */
   145     if (!added) {
   146         new_env = SDL_realloc(SDL_env, (i + 2) * sizeof(char *));
   147         if (new_env) {
   148             SDL_env = new_env;
   149             SDL_env[i++] = new_variable;
   150             SDL_env[i++] = (char *) 0;
   151             added = 1;
   152         } else {
   153             SDL_free(new_variable);
   154         }
   155     }
   156     return (added ? 0 : -1);
   157 }
   158 
   159 /* Retrieve a variable named "name" from the environment */
   160 char *
   161 SDL_getenv(const char *name)
   162 {
   163     int len, i;
   164     char *value;
   165 
   166     value = (char *) 0;
   167     if (SDL_env) {
   168         len = SDL_strlen(name);
   169         for (i = 0; SDL_env[i] && !value; ++i) {
   170             if ((SDL_strncmp(SDL_env[i], name, len) == 0) &&
   171                 (SDL_env[i][len] == '=')) {
   172                 value = &SDL_env[i][len + 1];
   173             }
   174         }
   175     }
   176     return value;
   177 }
   178 
   179 #endif /* __WIN32__ */
   180 
   181 #endif /* !HAVE_GETENV */
   182 
   183 #ifdef TEST_MAIN
   184 #include <stdio.h>
   185 
   186 int
   187 main(int argc, char *argv[])
   188 {
   189     char *value;
   190 
   191     printf("Checking for non-existent variable... ");
   192     fflush(stdout);
   193     if (!SDL_getenv("EXISTS")) {
   194         printf("okay\n");
   195     } else {
   196         printf("failed\n");
   197     }
   198     printf("Setting FIRST=VALUE1 in the environment... ");
   199     fflush(stdout);
   200     if (SDL_putenv("FIRST=VALUE1") == 0) {
   201         printf("okay\n");
   202     } else {
   203         printf("failed\n");
   204     }
   205     printf("Getting FIRST from the environment... ");
   206     fflush(stdout);
   207     value = SDL_getenv("FIRST");
   208     if (value && (SDL_strcmp(value, "VALUE1") == 0)) {
   209         printf("okay\n");
   210     } else {
   211         printf("failed\n");
   212     }
   213     printf("Setting SECOND=VALUE2 in the environment... ");
   214     fflush(stdout);
   215     if (SDL_putenv("SECOND=VALUE2") == 0) {
   216         printf("okay\n");
   217     } else {
   218         printf("failed\n");
   219     }
   220     printf("Getting SECOND from the environment... ");
   221     fflush(stdout);
   222     value = SDL_getenv("SECOND");
   223     if (value && (SDL_strcmp(value, "VALUE2") == 0)) {
   224         printf("okay\n");
   225     } else {
   226         printf("failed\n");
   227     }
   228     printf("Setting FIRST=NOVALUE in the environment... ");
   229     fflush(stdout);
   230     if (SDL_putenv("FIRST=NOVALUE") == 0) {
   231         printf("okay\n");
   232     } else {
   233         printf("failed\n");
   234     }
   235     printf("Getting FIRST from the environment... ");
   236     fflush(stdout);
   237     value = SDL_getenv("FIRST");
   238     if (value && (SDL_strcmp(value, "NOVALUE") == 0)) {
   239         printf("okay\n");
   240     } else {
   241         printf("failed\n");
   242     }
   243     printf("Checking for non-existent variable... ");
   244     fflush(stdout);
   245     if (!SDL_getenv("EXISTS")) {
   246         printf("okay\n");
   247     } else {
   248         printf("failed\n");
   249     }
   250     return (0);
   251 }
   252 #endif /* TEST_MAIN */
   253 /* vi: set ts=4 sw=4 expandtab: */