cscg22-gearboy

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

SDL_error.c (7388B)


      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/* Simple error handling in SDL */
     24
     25#include "SDL_log.h"
     26#include "SDL_error.h"
     27#include "SDL_error_c.h"
     28
     29
     30/* Routine to get the thread-specific error variable */
     31#if SDL_THREADS_DISABLED
     32/* The default (non-thread-safe) global error variable */
     33static SDL_error SDL_global_error;
     34#define SDL_GetErrBuf() (&SDL_global_error)
     35#else
     36extern SDL_error *SDL_GetErrBuf(void);
     37#endif /* SDL_THREADS_DISABLED */
     38
     39#define SDL_ERRBUFIZE   1024
     40
     41/* Private functions */
     42
     43static const char *
     44SDL_LookupString(const char *key)
     45{
     46    /* FIXME: Add code to lookup key in language string hash-table */
     47    return key;
     48}
     49
     50/* Public functions */
     51
     52int
     53SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
     54{
     55    va_list ap;
     56    SDL_error *error;
     57
     58    /* Ignore call if invalid format pointer was passed */
     59    if (fmt == NULL) return -1;
     60
     61    /* Copy in the key, mark error as valid */
     62    error = SDL_GetErrBuf();
     63    error->error = 1;
     64    SDL_strlcpy((char *) error->key, fmt, sizeof(error->key));
     65
     66    va_start(ap, fmt);
     67    error->argc = 0;
     68    while (*fmt) {
     69        if (*fmt++ == '%') {
     70            while (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) {
     71                ++fmt;
     72            }
     73            switch (*fmt++) {
     74            case 0:            /* Malformed format string.. */
     75                --fmt;
     76                break;
     77            case 'c':
     78            case 'i':
     79            case 'd':
     80            case 'u':
     81            case 'o':
     82            case 'x':
     83            case 'X':
     84                error->args[error->argc++].value_i = va_arg(ap, int);
     85                break;
     86            case 'f':
     87                error->args[error->argc++].value_f = va_arg(ap, double);
     88                break;
     89            case 'p':
     90                error->args[error->argc++].value_ptr = va_arg(ap, void *);
     91                break;
     92            case 's':
     93                {
     94                    int i = error->argc;
     95                    const char *str = va_arg(ap, const char *);
     96                    if (str == NULL)
     97                        str = "(null)";
     98                    SDL_strlcpy((char *) error->args[i].buf, str,
     99                                ERR_MAX_STRLEN);
    100                    error->argc++;
    101                }
    102                break;
    103            default:
    104                break;
    105            }
    106            if (error->argc >= ERR_MAX_ARGS) {
    107                break;
    108            }
    109        }
    110    }
    111    va_end(ap);
    112
    113    /* If we are in debug mode, print out an error message */
    114    SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", SDL_GetError());
    115
    116    return -1;
    117}
    118
    119/* This function has a bit more overhead than most error functions
    120   so that it supports internationalization and thread-safe errors.
    121*/
    122static char *
    123SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
    124{
    125    SDL_error *error;
    126
    127    /* Clear the error string */
    128    *errstr = '\0';
    129    --maxlen;
    130
    131    /* Get the thread-safe error, and print it out */
    132    error = SDL_GetErrBuf();
    133    if (error->error) {
    134        const char *fmt;
    135        char *msg = errstr;
    136        int len;
    137        int argi;
    138
    139        fmt = SDL_LookupString(error->key);
    140        argi = 0;
    141        while (*fmt && (maxlen > 0)) {
    142            if (*fmt == '%') {
    143                char tmp[32], *spot = tmp;
    144                *spot++ = *fmt++;
    145                while ((*fmt == '.' || (*fmt >= '0' && *fmt <= '9'))
    146                       && spot < (tmp + SDL_arraysize(tmp) - 2)) {
    147                    *spot++ = *fmt++;
    148                }
    149                *spot++ = *fmt++;
    150                *spot++ = '\0';
    151                switch (spot[-2]) {
    152                case '%':
    153                    *msg++ = '%';
    154                    maxlen -= 1;
    155                    break;
    156                case 'c':
    157                case 'i':
    158                case 'd':
    159                case 'u':
    160                case 'o':
    161                case 'x':
    162                case 'X':
    163                    len =
    164                        SDL_snprintf(msg, maxlen, tmp,
    165                                     error->args[argi++].value_i);
    166                    msg += len;
    167                    maxlen -= len;
    168                    break;
    169                case 'f':
    170                    len =
    171                        SDL_snprintf(msg, maxlen, tmp,
    172                                     error->args[argi++].value_f);
    173                    msg += len;
    174                    maxlen -= len;
    175                    break;
    176                case 'p':
    177                    len =
    178                        SDL_snprintf(msg, maxlen, tmp,
    179                                     error->args[argi++].value_ptr);
    180                    msg += len;
    181                    maxlen -= len;
    182                    break;
    183                case 's':
    184                    len =
    185                        SDL_snprintf(msg, maxlen, tmp,
    186                                     SDL_LookupString(error->args[argi++].
    187                                                      buf));
    188                    msg += len;
    189                    maxlen -= len;
    190                    break;
    191                }
    192            } else {
    193                *msg++ = *fmt++;
    194                maxlen -= 1;
    195            }
    196        }
    197        *msg = 0;               /* NULL terminate the string */
    198    }
    199    return (errstr);
    200}
    201
    202/* Available for backwards compatibility */
    203const char *
    204SDL_GetError(void)
    205{
    206    static char errmsg[SDL_ERRBUFIZE];
    207
    208    return SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE);
    209}
    210
    211void
    212SDL_ClearError(void)
    213{
    214    SDL_error *error;
    215
    216    error = SDL_GetErrBuf();
    217    error->error = 0;
    218}
    219
    220/* Very common errors go here */
    221int
    222SDL_Error(SDL_errorcode code)
    223{
    224    switch (code) {
    225    case SDL_ENOMEM:
    226        return SDL_SetError("Out of memory");
    227    case SDL_EFREAD:
    228        return SDL_SetError("Error reading from datastream");
    229    case SDL_EFWRITE:
    230        return SDL_SetError("Error writing to datastream");
    231    case SDL_EFSEEK:
    232        return SDL_SetError("Error seeking in datastream");
    233    case SDL_UNSUPPORTED:
    234        return SDL_SetError("That operation is not supported");
    235    default:
    236        return SDL_SetError("Unknown SDL error");
    237    }
    238}
    239
    240#ifdef TEST_ERROR
    241int
    242main(int argc, char *argv[])
    243{
    244    char buffer[BUFSIZ + 1];
    245
    246    SDL_SetError("Hi there!");
    247    printf("Error 1: %s\n", SDL_GetError());
    248    SDL_ClearError();
    249    SDL_memset(buffer, '1', BUFSIZ);
    250    buffer[BUFSIZ] = 0;
    251    SDL_SetError("This is the error: %s (%f)", buffer, 1.0);
    252    printf("Error 2: %s\n", SDL_GetError());
    253    exit(0);
    254}
    255#endif
    256
    257/* vi: set ts=4 sw=4 expandtab: */