src/SDL_error.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 06 May 2004 15:55:06 +0000
changeset 886 05c551e5bc64
parent 769 b8d311d90021
child 1172 f69f4d25fb20
permissions -rw-r--r--
Date: Sat, 24 Apr 2004 15:13:32 +0300
From: "Mike Gorchak"
Subject: SDL updates for the QNX6

1. Updated the README.QNX
2. Updated libtool scripts, which are shipped with SDL for QNX6 support.
3. Added some code to support the new QNX 6.3.0, which is in beta now.
4. Added code to detect the hw features, which driver supports.
5. Added hw alpha blits code.
6. Fixed bug when application switches to fullscreen more the 2 times. (afte\
r that window becames always stay on top).
7. Updated a bit README for the tests.
8. Added information about acceleration show in the testalpha.c test.
9. Added small fixes to the testoverlay2.c test.
10. Added alpha and cc+alpha blits benchmarks to the testvidinfo.c test.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@769
     3
    Copyright (C) 1997-2004 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
/* Simple error handling in SDL */
slouken@0
    29
slouken@0
    30
#include <stdio.h>
slouken@0
    31
#include <stdlib.h>
slouken@0
    32
#include <stdarg.h>
slouken@0
    33
#include <string.h>
slouken@0
    34
slouken@0
    35
#include "SDL_types.h"
slouken@0
    36
#include "SDL_getenv.h"
slouken@0
    37
#include "SDL_error.h"
slouken@0
    38
#include "SDL_error_c.h"
slouken@0
    39
#ifndef DISABLE_THREADS
slouken@0
    40
#include "SDL_thread_c.h"
slouken@0
    41
#endif
slouken@0
    42
slouken@0
    43
#ifdef DISABLE_THREADS
slouken@0
    44
/* The default (non-thread-safe) global error variable */
slouken@0
    45
static SDL_error SDL_global_error;
slouken@0
    46
slouken@0
    47
#define SDL_GetErrBuf()	(&SDL_global_error)
slouken@0
    48
#endif /* DISABLE_THREADS */
slouken@0
    49
slouken@1
    50
#ifdef __CYGWIN__
slouken@1
    51
#define DISABLE_STDIO
slouken@1
    52
#endif
slouken@1
    53
slouken@0
    54
#define SDL_ERRBUFIZE	1024
slouken@0
    55
slouken@0
    56
/* Private functions */
slouken@0
    57
slouken@0
    58
static void SDL_LookupString(const Uint8 *key, Uint16 *buf, int buflen)
slouken@0
    59
{
slouken@0
    60
	/* FIXME: Add code to lookup key in language string hash-table */
slouken@0
    61
slouken@0
    62
	/* Key not found in language string hash-table */
slouken@0
    63
	while ( *key && (--buflen > 0) ) {
slouken@0
    64
		*buf++ = *key++;
slouken@0
    65
	}
slouken@0
    66
	*buf = 0;	/* NULL terminate string */
slouken@0
    67
}
slouken@0
    68
slouken@0
    69
/* Public functions */
slouken@0
    70
slouken@0
    71
void SDL_SetError (const char *fmt, ...)
slouken@0
    72
{
slouken@0
    73
	va_list ap;
slouken@0
    74
	SDL_error *error;
slouken@0
    75
slouken@0
    76
	/* Copy in the key, mark error as valid */
slouken@0
    77
	error = SDL_GetErrBuf();
slouken@0
    78
	error->error = 1;
slouken@0
    79
	strncpy((char *)error->key, fmt, sizeof(error->key));
slouken@0
    80
	error->key[sizeof(error->key)-1] = '\0';
slouken@0
    81
slouken@0
    82
	va_start(ap, fmt);
slouken@0
    83
	error->argc = 0;
slouken@0
    84
	while ( *fmt ) {
slouken@0
    85
		if ( *fmt++ == '%' ) {
slouken@0
    86
			switch (*fmt++) {
slouken@0
    87
			    case 0:  /* Malformed format string.. */
slouken@0
    88
				--fmt;
slouken@0
    89
				break;
slouken@0
    90
#if 0	/* What is a character anyway?  (UNICODE issues) */
slouken@0
    91
			    case 'c':
slouken@0
    92
				error->args[error->argc++].value_c =
slouken@0
    93
						va_arg(ap, unsigned char);
slouken@0
    94
				break;
slouken@0
    95
#endif
slouken@0
    96
			    case 'd':
slouken@0
    97
				error->args[error->argc++].value_i =
slouken@0
    98
							va_arg(ap, int);
slouken@0
    99
				break;
slouken@0
   100
			    case 'f':
slouken@0
   101
				error->args[error->argc++].value_f =
slouken@0
   102
							va_arg(ap, double);
slouken@0
   103
				break;
slouken@0
   104
			    case 'p':
slouken@0
   105
				error->args[error->argc++].value_ptr =
slouken@0
   106
							va_arg(ap, void *);
slouken@0
   107
				break;
slouken@0
   108
			    case 's':
slouken@0
   109
				{
slouken@0
   110
				  int index = error->argc;
slouken@0
   111
				  strncpy((char *)error->args[index].buf,
slouken@0
   112
					va_arg(ap, char *), ERR_MAX_STRLEN);
slouken@0
   113
				  error->args[index].buf[ERR_MAX_STRLEN-1] = 0;
slouken@0
   114
				  error->argc++;
slouken@0
   115
				}
slouken@0
   116
				break;
slouken@0
   117
			    default:
slouken@0
   118
				break;
slouken@0
   119
			}
slouken@0
   120
			if ( error->argc >= ERR_MAX_ARGS ) {
slouken@0
   121
				break;
slouken@0
   122
			}
slouken@0
   123
		}
slouken@0
   124
	}
slouken@0
   125
	va_end(ap);
slouken@0
   126
slouken@1
   127
#ifndef DISABLE_STDIO
slouken@0
   128
	/* If we are in debug mode, print out an error message */
slouken@0
   129
#ifdef DEBUG_ERROR
slouken@0
   130
	fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
slouken@0
   131
#else
slouken@0
   132
	if ( getenv("SDL_DEBUG") ) {
slouken@0
   133
		fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
slouken@0
   134
	}
slouken@0
   135
#endif
slouken@1
   136
#endif /* !DISABLE_STDIO */
slouken@0
   137
}
slouken@0
   138
slouken@0
   139
/* Print out an integer value to a UNICODE buffer */
slouken@0
   140
static int PrintInt(Uint16 *str, unsigned int maxlen, int value)
slouken@0
   141
{
slouken@0
   142
	char tmp[128];
slouken@0
   143
	int len, i;
slouken@0
   144
slouken@0
   145
	sprintf(tmp, "%d", value);
slouken@0
   146
	len = 0;
slouken@0
   147
	if ( strlen(tmp) < maxlen ) {
slouken@0
   148
		for ( i=0; tmp[i]; ++i ) {
slouken@0
   149
			*str++ = tmp[i];
slouken@0
   150
			++len;
slouken@0
   151
		}
slouken@0
   152
	}
slouken@0
   153
	return(len);
slouken@0
   154
}
slouken@0
   155
/* Print out a double value to a UNICODE buffer */
slouken@0
   156
static int PrintDouble(Uint16 *str, unsigned int maxlen, double value)
slouken@0
   157
{
slouken@0
   158
	char tmp[128];
slouken@0
   159
	int len, i;
slouken@0
   160
slouken@0
   161
	sprintf(tmp, "%f", value);
slouken@0
   162
	len = 0;
slouken@0
   163
	if ( strlen(tmp) < maxlen ) {
slouken@0
   164
		for ( i=0; tmp[i]; ++i ) {
slouken@0
   165
			*str++ = tmp[i];
slouken@0
   166
			++len;
slouken@0
   167
		}
slouken@0
   168
	}
slouken@0
   169
	return(len);
slouken@0
   170
}
slouken@0
   171
/* Print out a pointer value to a UNICODE buffer */
slouken@0
   172
static int PrintPointer(Uint16 *str, unsigned int maxlen, void *value)
slouken@0
   173
{
slouken@0
   174
	char tmp[128];
slouken@0
   175
	int len, i;
slouken@0
   176
slouken@0
   177
	sprintf(tmp, "%p", value);
slouken@0
   178
	len = 0;
slouken@0
   179
	if ( strlen(tmp) < maxlen ) {
slouken@0
   180
		for ( i=0; tmp[i]; ++i ) {
slouken@0
   181
			*str++ = tmp[i];
slouken@0
   182
			++len;
slouken@0
   183
		}
slouken@0
   184
	}
slouken@0
   185
	return(len);
slouken@0
   186
}
slouken@0
   187
slouken@0
   188
/* This function has a bit more overhead than most error functions
slouken@0
   189
   so that it supports internationalization and thread-safe errors.
slouken@0
   190
*/
slouken@0
   191
Uint16 *SDL_GetErrorMsgUNICODE(Uint16 *errstr, unsigned int maxlen)
slouken@0
   192
{
slouken@0
   193
	SDL_error *error;
slouken@0
   194
slouken@0
   195
	/* Clear the error string */
slouken@0
   196
	*errstr = 0; --maxlen;
slouken@0
   197
slouken@0
   198
	/* Get the thread-safe error, and print it out */
slouken@0
   199
	error = SDL_GetErrBuf();
slouken@0
   200
	if ( error->error ) {
slouken@0
   201
		Uint16 translated[ERR_MAX_STRLEN], *fmt, *msg;
slouken@0
   202
		int len;
slouken@0
   203
		int argi;
slouken@0
   204
slouken@0
   205
		/* Print out the UNICODE error message */
slouken@0
   206
		SDL_LookupString(error->key, translated, sizeof(translated));
slouken@0
   207
		msg = errstr;
slouken@0
   208
		argi = 0;
slouken@0
   209
		for ( fmt=translated; *fmt && (maxlen > 0); ) {
slouken@0
   210
			if ( *fmt == '%' ) {
slouken@0
   211
				switch (fmt[1]) {
slouken@0
   212
				    case 'S':	/* Special SKIP operand */
slouken@0
   213
					argi += (fmt[2] - '0');
slouken@0
   214
					++fmt;
slouken@0
   215
					break;
slouken@0
   216
				    case '%':
slouken@0
   217
					*msg++ = '%';
slouken@0
   218
					maxlen -= 1;
slouken@0
   219
					break;
slouken@0
   220
#if 0	/* What is a character anyway?  (UNICODE issues) */
slouken@0
   221
				    case 'c':
slouken@0
   222
                                        *msg++ = (unsigned char)
slouken@0
   223
					         error->args[argi++].value_c;
slouken@0
   224
					maxlen -= 1;
slouken@0
   225
					break;
slouken@0
   226
#endif
slouken@0
   227
				    case 'd':
slouken@0
   228
					len = PrintInt(msg, maxlen,
slouken@0
   229
						error->args[argi++].value_i);
slouken@0
   230
					msg += len;
slouken@0
   231
					maxlen -= len;
slouken@0
   232
					break;
slouken@0
   233
				    case 'f':
slouken@0
   234
					len = PrintDouble(msg, maxlen,
slouken@0
   235
						error->args[argi++].value_f);
slouken@0
   236
					msg += len;
slouken@0
   237
					maxlen -= len;
slouken@0
   238
					break;
slouken@0
   239
				    case 'p':
slouken@0
   240
					len = PrintPointer(msg, maxlen,
slouken@0
   241
						error->args[argi++].value_ptr);
slouken@0
   242
					msg += len;
slouken@0
   243
					maxlen -= len;
slouken@0
   244
					break;
slouken@0
   245
				    case 's': /* UNICODE string */
slouken@0
   246
					{ Uint16 buf[ERR_MAX_STRLEN], *str;
slouken@0
   247
					  SDL_LookupString(error->args[argi++].buf, buf, sizeof(buf));
slouken@0
   248
					  str = buf;
slouken@0
   249
					  while ( *str && (maxlen > 0) ) {
slouken@0
   250
						*msg++ = *str++;
slouken@0
   251
						maxlen -= 1;
slouken@0
   252
					  }
slouken@0
   253
					}
slouken@0
   254
					break;
slouken@0
   255
				}
slouken@0
   256
				fmt += 2;
slouken@0
   257
			} else {
slouken@0
   258
				*msg++ = *fmt++;
slouken@0
   259
				maxlen -= 1;
slouken@0
   260
			}
slouken@0
   261
		}
slouken@0
   262
		*msg = 0;	/* NULL terminate the string */
slouken@0
   263
	}
slouken@0
   264
	return(errstr);
slouken@0
   265
}
slouken@0
   266
slouken@0
   267
Uint8 *SDL_GetErrorMsg(Uint8 *errstr, unsigned int maxlen)
slouken@0
   268
{
slouken@0
   269
	Uint16 *errstr16;
slouken@0
   270
	unsigned int i;
slouken@0
   271
slouken@0
   272
	/* Allocate the UNICODE buffer */
slouken@0
   273
	errstr16 = (Uint16 *)malloc(maxlen * (sizeof *errstr16));
slouken@0
   274
	if ( ! errstr16 ) {
slouken@0
   275
		strncpy((char *)errstr, "Out of memory", maxlen);
slouken@0
   276
		errstr[maxlen-1] = '\0';
slouken@0
   277
		return(errstr);
slouken@0
   278
	}
slouken@0
   279
slouken@0
   280
	/* Get the error message */
slouken@0
   281
	SDL_GetErrorMsgUNICODE(errstr16, maxlen);
slouken@0
   282
slouken@0
   283
	/* Convert from UNICODE to Latin1 encoding */
slouken@0
   284
	for ( i=0; i<maxlen; ++i ) {
slouken@0
   285
		errstr[i] = (Uint8)errstr16[i];
slouken@0
   286
	}
slouken@0
   287
slouken@0
   288
	/* Free UNICODE buffer (if necessary) */
slouken@0
   289
	free(errstr16);
slouken@0
   290
slouken@0
   291
	return(errstr);
slouken@0
   292
}
slouken@0
   293
slouken@0
   294
/* Available for backwards compatibility */
slouken@0
   295
char *SDL_GetError (void)
slouken@0
   296
{
slouken@0
   297
	static char errmsg[SDL_ERRBUFIZE];
slouken@0
   298
slouken@0
   299
	return((char *)SDL_GetErrorMsg((unsigned char *)errmsg, SDL_ERRBUFIZE));
slouken@0
   300
}
slouken@0
   301
slouken@0
   302
void SDL_ClearError(void)
slouken@0
   303
{
slouken@0
   304
	SDL_error *error;
slouken@0
   305
slouken@0
   306
	error = SDL_GetErrBuf();
slouken@0
   307
	error->error = 0;
slouken@0
   308
}
slouken@0
   309
slouken@0
   310
/* Very common errors go here */
slouken@0
   311
void SDL_Error(SDL_errorcode code)
slouken@0
   312
{
slouken@0
   313
	switch (code) {
slouken@0
   314
		case SDL_ENOMEM:
slouken@0
   315
			SDL_SetError("Out of memory");
slouken@0
   316
			break;
slouken@0
   317
		case SDL_EFREAD:
slouken@0
   318
			SDL_SetError("Error reading from datastream");
slouken@0
   319
			break;
slouken@0
   320
		case SDL_EFWRITE:
slouken@0
   321
			SDL_SetError("Error writing to datastream");
slouken@0
   322
			break;
slouken@0
   323
		case SDL_EFSEEK:
slouken@0
   324
			SDL_SetError("Error seeking in datastream");
slouken@0
   325
			break;
slouken@0
   326
		default:
slouken@0
   327
			SDL_SetError("Unknown SDL error");
slouken@0
   328
			break;
slouken@0
   329
	}
slouken@0
   330
}
slouken@0
   331
slouken@0
   332
#ifdef TEST_ERROR
slouken@0
   333
int main(int argc, char *argv[])
slouken@0
   334
{
slouken@0
   335
	char buffer[BUFSIZ+1];
slouken@0
   336
slouken@0
   337
	SDL_SetError("Hi there!");
slouken@0
   338
	printf("Error 1: %s\n", SDL_GetError());
slouken@0
   339
	SDL_ClearError();
slouken@0
   340
	memset(buffer, '1', BUFSIZ);
slouken@0
   341
	buffer[BUFSIZ] = 0;
slouken@0
   342
	SDL_SetError("This is the error: %s (%f)", buffer, 1.0);
slouken@0
   343
	printf("Error 2: %s\n", SDL_GetError());
slouken@0
   344
	exit(0);
slouken@0
   345
}
slouken@0
   346
#endif