SDL_error.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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