src/stdlib/SDL_getenv.c
author Ryan C. Gordon <icculus@icculus.org>
Sat, 15 Sep 2012 10:59:39 -0400
changeset 6430 48d519500f7e
parent 6138 4c64952a58fb
child 6885 700f1b25f77f
permissions -rwxr-xr-x
Removed Windows CE support from SDL 2.0.

It's a long-dead platform, and we don't have any way to build for, test, or
maintain it, so there's no sense in doing acrobatics to support it.

If you need Windows CE support, use SDL 1.2. If you need Windows Phone support,
send SDL 2.0 patches for the newer Windows Mobile platform.
slouken@1330
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@1330
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1330
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1330
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1330
    20
*/
slouken@1402
    21
#include "SDL_config.h"
slouken@1330
    22
slouken@1354
    23
#include "SDL_stdinc.h"
slouken@1330
    24
slouken@1331
    25
#ifndef HAVE_GETENV
slouken@1330
    26
icculus@6430
    27
#if defined(__WIN32__)
slouken@1330
    28
slouken@5090
    29
#include "../core/windows/SDL_windows.h"
slouken@1330
    30
slouken@1330
    31
/* Note this isn't thread-safe! */
slouken@1330
    32
slouken@1895
    33
static char *SDL_envmem = NULL; /* Ugh, memory leak */
slouken@1456
    34
static size_t SDL_envmemlen = 0;
slouken@1330
    35
icculus@3581
    36
/* Put a variable into the environment */
slouken@1895
    37
int
icculus@3581
    38
SDL_setenv(const char *name, const char *value, int overwrite)
slouken@1330
    39
{
icculus@3581
    40
    if (!overwrite) {
icculus@3581
    41
        char ch = 0;
slouken@5090
    42
        const size_t len = GetEnvironmentVariableA(name, &ch, sizeof (ch));
icculus@3581
    43
        if (len > 0) {
icculus@3581
    44
            return 0;  /* asked not to overwrite existing value. */
icculus@3581
    45
        }
slouken@1895
    46
    }
slouken@5090
    47
    if (!SetEnvironmentVariableA(name, *value ? value : NULL)) {
slouken@1895
    48
        return -1;
slouken@1895
    49
    }
slouken@1895
    50
    return 0;
slouken@1330
    51
}
slouken@1330
    52
slouken@1330
    53
/* Retrieve a variable named "name" from the environment */
slouken@1895
    54
char *
slouken@1895
    55
SDL_getenv(const char *name)
slouken@1330
    56
{
slouken@1895
    57
    size_t bufferlen;
slouken@1330
    58
slouken@1895
    59
    bufferlen =
slouken@5090
    60
        GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen);
slouken@1895
    61
    if (bufferlen == 0) {
slouken@1895
    62
        return NULL;
slouken@1895
    63
    }
slouken@1895
    64
    if (bufferlen > SDL_envmemlen) {
slouken@1895
    65
        char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen);
slouken@1895
    66
        if (newmem == NULL) {
slouken@1895
    67
            return NULL;
slouken@1895
    68
        }
slouken@1895
    69
        SDL_envmem = newmem;
slouken@1895
    70
        SDL_envmemlen = bufferlen;
slouken@5090
    71
        GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen);
slouken@1895
    72
    }
slouken@1895
    73
    return SDL_envmem;
slouken@1330
    74
}
slouken@1330
    75
slouken@1330
    76
#else /* roll our own */
slouken@1330
    77
slouken@1895
    78
static char **SDL_env = (char **) 0;
slouken@1330
    79
icculus@3581
    80
/* Put a variable into the environment */
slouken@1895
    81
int
icculus@3581
    82
SDL_setenv(const char *name, const char *value, int overwrite)
slouken@1330
    83
{
slouken@1895
    84
    int added;
slouken@1895
    85
    int len, i;
slouken@1895
    86
    char **new_env;
slouken@1895
    87
    char *new_variable;
slouken@1330
    88
slouken@1895
    89
    /* A little error checking */
icculus@3581
    90
    if (!name || !value) {
slouken@1895
    91
        return (-1);
slouken@1895
    92
    }
slouken@1330
    93
slouken@3583
    94
    /* See if it already exists */
slouken@3583
    95
    if (!overwrite && SDL_getenv(name)) {
slouken@3583
    96
        return 0;
slouken@3583
    97
    }
slouken@3583
    98
slouken@1895
    99
    /* Allocate memory for the variable */
icculus@3581
   100
    len = SDL_strlen(name) + SDL_strlen(value) + 2;
icculus@3581
   101
    new_variable = (char *) SDL_malloc(len);
slouken@1895
   102
    if (!new_variable) {
slouken@1895
   103
        return (-1);
slouken@1895
   104
    }
slouken@1330
   105
icculus@3581
   106
    SDL_snprintf(new_variable, len, "%s=%s", name, value);
icculus@3581
   107
    value = new_variable + SDL_strlen(name) + 1;
icculus@3581
   108
    name = new_variable;
icculus@3581
   109
slouken@1895
   110
    /* Actually put it into the environment */
slouken@1895
   111
    added = 0;
slouken@1895
   112
    i = 0;
slouken@1895
   113
    if (SDL_env) {
slouken@1895
   114
        /* Check to see if it's already there... */
slouken@1895
   115
        len = (value - name);
slouken@1895
   116
        for (; SDL_env[i]; ++i) {
slouken@1895
   117
            if (SDL_strncmp(SDL_env[i], name, len) == 0) {
slouken@1895
   118
                break;
slouken@1895
   119
            }
slouken@1895
   120
        }
slouken@1895
   121
        /* If we found it, just replace the entry */
slouken@1895
   122
        if (SDL_env[i]) {
slouken@1895
   123
            SDL_free(SDL_env[i]);
slouken@1895
   124
            SDL_env[i] = new_variable;
slouken@1895
   125
            added = 1;
slouken@1895
   126
        }
slouken@1895
   127
    }
slouken@1330
   128
slouken@1895
   129
    /* Didn't find it in the environment, expand and add */
slouken@1895
   130
    if (!added) {
slouken@1895
   131
        new_env = SDL_realloc(SDL_env, (i + 2) * sizeof(char *));
slouken@1895
   132
        if (new_env) {
slouken@1895
   133
            SDL_env = new_env;
slouken@1895
   134
            SDL_env[i++] = new_variable;
slouken@1895
   135
            SDL_env[i++] = (char *) 0;
slouken@1895
   136
            added = 1;
slouken@1895
   137
        } else {
slouken@1895
   138
            SDL_free(new_variable);
slouken@1895
   139
        }
slouken@1895
   140
    }
slouken@1895
   141
    return (added ? 0 : -1);
slouken@1330
   142
}
slouken@1330
   143
slouken@1330
   144
/* Retrieve a variable named "name" from the environment */
slouken@1895
   145
char *
slouken@1895
   146
SDL_getenv(const char *name)
slouken@1330
   147
{
slouken@1895
   148
    int len, i;
slouken@1895
   149
    char *value;
slouken@1330
   150
slouken@1895
   151
    value = (char *) 0;
slouken@1895
   152
    if (SDL_env) {
slouken@1895
   153
        len = SDL_strlen(name);
slouken@1895
   154
        for (i = 0; SDL_env[i] && !value; ++i) {
slouken@1895
   155
            if ((SDL_strncmp(SDL_env[i], name, len) == 0) &&
slouken@1895
   156
                (SDL_env[i][len] == '=')) {
slouken@1895
   157
                value = &SDL_env[i][len + 1];
slouken@1895
   158
            }
slouken@1895
   159
        }
slouken@1895
   160
    }
slouken@1895
   161
    return value;
slouken@1330
   162
}
slouken@1330
   163
slouken@5086
   164
#endif /* __WIN32__ */
slouken@1330
   165
slouken@1331
   166
#endif /* !HAVE_GETENV */
slouken@1331
   167
icculus@3581
   168
icculus@3581
   169
/* We have a real environment table, but no real setenv? Fake it w/ putenv. */
icculus@3581
   170
#if (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV))
icculus@3581
   171
int
icculus@3581
   172
SDL_setenv(const char *name, const char *value, int overwrite)
icculus@3581
   173
{
icculus@3581
   174
    size_t len;
icculus@3581
   175
    char *new_variable;
icculus@3581
   176
icculus@3581
   177
    if (getenv(name) != NULL) {
icculus@3581
   178
        if (overwrite) {
icculus@3581
   179
            unsetenv(name);
icculus@3581
   180
        } else {
icculus@3581
   181
            return 0;  /* leave the existing one there. */
icculus@3581
   182
        }
icculus@3581
   183
    }
icculus@3581
   184
icculus@3581
   185
    /* This leaks. Sorry. Get a better OS so we don't have to do this. */
icculus@3581
   186
    len = SDL_strlen(name) + SDL_strlen(value) + 2;
icculus@3581
   187
    new_variable = (char *) SDL_malloc(len);
icculus@3581
   188
    if (!new_variable) {
icculus@3581
   189
        return (-1);
icculus@3581
   190
    }
icculus@3581
   191
icculus@3581
   192
    SDL_snprintf(new_variable, len, "%s=%s", name, value);
icculus@3581
   193
    return putenv(new_variable);
icculus@3581
   194
}
icculus@3581
   195
#endif
icculus@3581
   196
icculus@3581
   197
slouken@1330
   198
#ifdef TEST_MAIN
slouken@1330
   199
#include <stdio.h>
slouken@1330
   200
slouken@1895
   201
int
slouken@1895
   202
main(int argc, char *argv[])
slouken@1330
   203
{
slouken@1895
   204
    char *value;
slouken@1330
   205
slouken@1895
   206
    printf("Checking for non-existent variable... ");
slouken@1895
   207
    fflush(stdout);
slouken@1895
   208
    if (!SDL_getenv("EXISTS")) {
slouken@1895
   209
        printf("okay\n");
slouken@1895
   210
    } else {
slouken@1895
   211
        printf("failed\n");
slouken@1895
   212
    }
slouken@1895
   213
    printf("Setting FIRST=VALUE1 in the environment... ");
slouken@1895
   214
    fflush(stdout);
slouken@3591
   215
    if (SDL_setenv("FIRST", "VALUE1", 0) == 0) {
slouken@1895
   216
        printf("okay\n");
slouken@1895
   217
    } else {
slouken@1895
   218
        printf("failed\n");
slouken@1895
   219
    }
slouken@1895
   220
    printf("Getting FIRST from the environment... ");
slouken@1895
   221
    fflush(stdout);
slouken@1895
   222
    value = SDL_getenv("FIRST");
slouken@1895
   223
    if (value && (SDL_strcmp(value, "VALUE1") == 0)) {
slouken@1895
   224
        printf("okay\n");
slouken@1895
   225
    } else {
slouken@1895
   226
        printf("failed\n");
slouken@1895
   227
    }
slouken@1895
   228
    printf("Setting SECOND=VALUE2 in the environment... ");
slouken@1895
   229
    fflush(stdout);
slouken@3591
   230
    if (SDL_setenv("SECOND", "VALUE2", 0) == 0) {
slouken@1895
   231
        printf("okay\n");
slouken@1895
   232
    } else {
slouken@1895
   233
        printf("failed\n");
slouken@1895
   234
    }
slouken@1895
   235
    printf("Getting SECOND from the environment... ");
slouken@1895
   236
    fflush(stdout);
slouken@1895
   237
    value = SDL_getenv("SECOND");
slouken@1895
   238
    if (value && (SDL_strcmp(value, "VALUE2") == 0)) {
slouken@1895
   239
        printf("okay\n");
slouken@1895
   240
    } else {
slouken@1895
   241
        printf("failed\n");
slouken@1895
   242
    }
slouken@1895
   243
    printf("Setting FIRST=NOVALUE in the environment... ");
slouken@1895
   244
    fflush(stdout);
slouken@3591
   245
    if (SDL_setenv("FIRST", "NOVALUE", 1) == 0) {
slouken@1895
   246
        printf("okay\n");
slouken@1895
   247
    } else {
slouken@1895
   248
        printf("failed\n");
slouken@1895
   249
    }
slouken@1895
   250
    printf("Getting FIRST from the environment... ");
slouken@1895
   251
    fflush(stdout);
slouken@1895
   252
    value = SDL_getenv("FIRST");
slouken@1895
   253
    if (value && (SDL_strcmp(value, "NOVALUE") == 0)) {
slouken@1895
   254
        printf("okay\n");
slouken@1895
   255
    } else {
slouken@1895
   256
        printf("failed\n");
slouken@1895
   257
    }
slouken@1895
   258
    printf("Checking for non-existent variable... ");
slouken@1895
   259
    fflush(stdout);
slouken@1895
   260
    if (!SDL_getenv("EXISTS")) {
slouken@1895
   261
        printf("okay\n");
slouken@1895
   262
    } else {
slouken@1895
   263
        printf("failed\n");
slouken@1895
   264
    }
slouken@1895
   265
    return (0);
slouken@1330
   266
}
slouken@1330
   267
#endif /* TEST_MAIN */
slouken@3591
   268
slouken@1895
   269
/* vi: set ts=4 sw=4 expandtab: */