cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_getenv.c (8138B)


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