src/SDL_error.c
author David Ludwig <dludwig@pobox.com>
Wed, 25 Dec 2013 21:39:48 -0500
changeset 8563 c0e68f3b6bbb
parent 7191 75360622e65f
child 8093 b43765095a6f
permissions -rw-r--r--
WinRT: compiled the d3d11 renderer's shaders into SDL itself

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