Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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