src/SDL_error.c
branchSDL-1.3
changeset 1659 14717b52abc0
parent 1612 97d0966f4bf7
child 1662 782fd950bd46
equal deleted inserted replaced
1658:e49147870aac 1659:14717b52abc0
    37 
    37 
    38 #define SDL_ERRBUFIZE	1024
    38 #define SDL_ERRBUFIZE	1024
    39 
    39 
    40 /* Private functions */
    40 /* Private functions */
    41 
    41 
    42 static void SDL_LookupString(const Uint8 *key, Uint16 *buf, int buflen)
    42 static const char *SDL_LookupString(const char *key)
    43 {
    43 {
    44 	/* FIXME: Add code to lookup key in language string hash-table */
    44 	/* FIXME: Add code to lookup key in language string hash-table */
    45 
    45 	return key;
    46 	/* Key not found in language string hash-table */
       
    47 	while ( *key && (--buflen > 0) ) {
       
    48 		*buf++ = *key++;
       
    49 	}
       
    50 	*buf = 0;	/* NULL terminate string */
       
    51 }
    46 }
    52 
    47 
    53 /* Public functions */
    48 /* Public functions */
    54 
    49 
    55 void SDL_SetError (const char *fmt, ...)
    50 void SDL_SetError (const char *fmt, ...)
    64 
    59 
    65 	va_start(ap, fmt);
    60 	va_start(ap, fmt);
    66 	error->argc = 0;
    61 	error->argc = 0;
    67 	while ( *fmt ) {
    62 	while ( *fmt ) {
    68 		if ( *fmt++ == '%' ) {
    63 		if ( *fmt++ == '%' ) {
       
    64 			while ( *fmt == '.' || (*fmt >= '0' && *fmt <= '9') ) {
       
    65 				++fmt;
       
    66 			}
    69 			switch (*fmt++) {
    67 			switch (*fmt++) {
    70 			    case 0:  /* Malformed format string.. */
    68 			    case 0:  /* Malformed format string.. */
    71 				--fmt;
    69 				--fmt;
    72 				break;
    70 				break;
    73 #if 0	/* What is a character anyway?  (UNICODE issues) */
       
    74 			    case 'c':
    71 			    case 'c':
    75 				error->args[error->argc++].value_c =
    72 			    case 'i':
    76 						va_arg(ap, unsigned char);
       
    77 				break;
       
    78 #endif
       
    79 			    case 'd':
    73 			    case 'd':
       
    74 			    case 'u':
       
    75 			    case 'o':
       
    76 			    case 'x':
       
    77 			    case 'X':
    80 				error->args[error->argc++].value_i =
    78 				error->args[error->argc++].value_i =
    81 							va_arg(ap, int);
    79 							va_arg(ap, int);
    82 				break;
    80 				break;
    83 			    case 'f':
    81 			    case 'f':
    84 				error->args[error->argc++].value_f =
    82 				error->args[error->argc++].value_f =
   112 #ifdef DEBUG_ERROR
   110 #ifdef DEBUG_ERROR
   113 	fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
   111 	fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
   114 #endif
   112 #endif
   115 }
   113 }
   116 
   114 
   117 /* Print out an integer value to a UNICODE buffer */
       
   118 static int PrintInt(Uint16 *str, unsigned int maxlen, int value)
       
   119 {
       
   120 	char tmp[128];
       
   121 	int len, i;
       
   122 
       
   123 	SDL_snprintf(tmp, SDL_arraysize(tmp), "%d", value);
       
   124 	len = 0;
       
   125 	if ( SDL_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 
       
   139 	SDL_snprintf(tmp, SDL_arraysize(tmp), "%f", value);
       
   140 	len = 0;
       
   141 	if ( SDL_strlen(tmp) < maxlen ) {
       
   142 		for ( i=0; tmp[i]; ++i ) {
       
   143 			*str++ = tmp[i];
       
   144 			++len;
       
   145 		}
       
   146 	}
       
   147 	return(len);
       
   148 }
       
   149 /* Print out a pointer value to a UNICODE buffer */
       
   150 static int PrintPointer(Uint16 *str, unsigned int maxlen, void *value)
       
   151 {
       
   152 	char tmp[128];
       
   153 	int len, i;
       
   154 
       
   155 	SDL_snprintf(tmp, SDL_arraysize(tmp), "%p", value);
       
   156 	len = 0;
       
   157 	if ( SDL_strlen(tmp) < maxlen ) {
       
   158 		for ( i=0; tmp[i]; ++i ) {
       
   159 			*str++ = tmp[i];
       
   160 			++len;
       
   161 		}
       
   162 	}
       
   163 	return(len);
       
   164 }
       
   165 
       
   166 /* This function has a bit more overhead than most error functions
   115 /* This function has a bit more overhead than most error functions
   167    so that it supports internationalization and thread-safe errors.
   116    so that it supports internationalization and thread-safe errors.
   168 */
   117 */
   169 Uint16 *SDL_GetErrorMsgUNICODE(Uint16 *errstr, unsigned int maxlen)
   118 char *SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
   170 {
   119 {
   171 	SDL_error *error;
   120 	SDL_error *error;
   172 
   121 
   173 	/* Clear the error string */
   122 	/* Clear the error string */
   174 	*errstr = 0; --maxlen;
   123 	*errstr = '\0'; --maxlen;
   175 
   124 
   176 	/* Get the thread-safe error, and print it out */
   125 	/* Get the thread-safe error, and print it out */
   177 	error = SDL_GetErrBuf();
   126 	error = SDL_GetErrBuf();
   178 	if ( error->error ) {
   127 	if ( error->error ) {
   179 		Uint16 translated[ERR_MAX_STRLEN], *fmt, *msg;
   128 		const char *fmt;
       
   129 		char *msg = errstr;
   180 		int len;
   130 		int len;
   181 		int argi;
   131 		int argi;
   182 
   132 
   183 		/* Print out the UNICODE error message */
   133 		fmt = SDL_LookupString(error->key);
   184 		SDL_LookupString(error->key, translated, sizeof(translated));
       
   185 		msg = errstr;
       
   186 		argi = 0;
   134 		argi = 0;
   187 		for ( fmt=translated; *fmt && (maxlen > 0); ) {
   135 		while ( *fmt && (maxlen > 0) ) {
   188 			if ( *fmt == '%' ) {
   136 			if ( *fmt == '%' ) {
   189 				switch (fmt[1]) {
   137 				char tmp[32], *spot = tmp;
   190 				    case 'S':	/* Special SKIP operand */
   138 				*spot++ = *fmt++;
   191 					argi += (fmt[2] - '0');
   139 				while ( (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) && spot < (tmp+SDL_arraysize(tmp)-2) ) {
   192 					++fmt;
   140 					*spot++ = *fmt++;
   193 					break;
   141 				}
       
   142 				*spot++ = *fmt++;
       
   143 				*spot++ = '\0';
       
   144 				switch (spot[-2]) {
   194 				    case '%':
   145 				    case '%':
   195 					*msg++ = '%';
   146 					*msg++ = '%';
   196 					maxlen -= 1;
   147 					maxlen -= 1;
   197 					break;
   148 					break;
   198 #if 0	/* What is a character anyway?  (UNICODE issues) */
       
   199 				    case 'c':
   149 				    case 'c':
   200                                         *msg++ = (unsigned char)
   150 				    case 'i':
   201 					         error->args[argi++].value_c;
   151 			            case 'd':
   202 					maxlen -= 1;
   152 			            case 'u':
   203 					break;
   153 			            case 'o':
   204 #endif
   154 				    case 'x':
   205 				    case 'd':
   155 				    case 'X':
   206 					len = PrintInt(msg, maxlen,
   156 					len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_i);
   207 						error->args[argi++].value_i);
       
   208 					msg += len;
   157 					msg += len;
   209 					maxlen -= len;
   158 					maxlen -= len;
   210 					break;
   159 					break;
   211 				    case 'f':
   160 				    case 'f':
   212 					len = PrintDouble(msg, maxlen,
   161 					len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_f);
   213 						error->args[argi++].value_f);
       
   214 					msg += len;
   162 					msg += len;
   215 					maxlen -= len;
   163 					maxlen -= len;
   216 					break;
   164 					break;
   217 				    case 'p':
   165 				    case 'p':
   218 					len = PrintPointer(msg, maxlen,
   166 					len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_ptr);
   219 						error->args[argi++].value_ptr);
   167 					msg += len;
   220 					msg += len;
   168 					maxlen -= len;
   221 					maxlen -= len;
   169 					break;
   222 					break;
   170 				    case 's':
   223 				    case 's': /* UNICODE string */
   171 					len = SDL_snprintf(msg, maxlen, tmp, SDL_LookupString(error->args[argi++].buf));
   224 					{ Uint16 buf[ERR_MAX_STRLEN], *str;
   172 					msg += len;
   225 					  SDL_LookupString(error->args[argi++].buf, buf, sizeof(buf));
   173 					maxlen -= len;
   226 					  str = buf;
       
   227 					  while ( *str && (maxlen > 0) ) {
       
   228 						*msg++ = *str++;
       
   229 						maxlen -= 1;
       
   230 					  }
       
   231 					}
       
   232 					break;
   174 					break;
   233 				}
   175 				}
   234 				fmt += 2;
       
   235 			} else {
   176 			} else {
   236 				*msg++ = *fmt++;
   177 				*msg++ = *fmt++;
   237 				maxlen -= 1;
   178 				maxlen -= 1;
   238 			}
   179 			}
   239 		}
   180 		}
   240 		*msg = 0;	/* NULL terminate the string */
   181 		*msg = 0;	/* NULL terminate the string */
   241 	}
   182 	}
   242 	return(errstr);
   183 	return(errstr);
   243 }
   184 }
   244 
   185 
   245 Uint8 *SDL_GetErrorMsg(Uint8 *errstr, unsigned int maxlen)
       
   246 {
       
   247 	Uint16 *errstr16;
       
   248 	unsigned int i;
       
   249 
       
   250 	/* Allocate the UNICODE buffer */
       
   251 	errstr16 = (Uint16 *)SDL_malloc(maxlen * (sizeof *errstr16));
       
   252 	if ( ! errstr16 ) {
       
   253 		SDL_strlcpy((char *)errstr, "Out of memory", maxlen);
       
   254 		return(errstr);
       
   255 	}
       
   256 
       
   257 	/* Get the error message */
       
   258 	SDL_GetErrorMsgUNICODE(errstr16, maxlen);
       
   259 
       
   260 	/* Convert from UNICODE to Latin1 encoding */
       
   261 	for ( i=0; i<maxlen; ++i ) {
       
   262 		errstr[i] = (Uint8)errstr16[i];
       
   263 	}
       
   264 
       
   265 	/* Free UNICODE buffer (if necessary) */
       
   266 	SDL_free(errstr16);
       
   267 
       
   268 	return(errstr);
       
   269 }
       
   270 
       
   271 /* Available for backwards compatibility */
   186 /* Available for backwards compatibility */
   272 char *SDL_GetError (void)
   187 char *SDL_GetError (void)
   273 {
   188 {
   274 	static char errmsg[SDL_ERRBUFIZE];
   189 	static char errmsg[SDL_ERRBUFIZE];
   275 
   190 
   276 	return((char *)SDL_GetErrorMsg((unsigned char *)errmsg, SDL_ERRBUFIZE));
   191 	return((char *)SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE));
   277 }
   192 }
   278 
   193 
   279 void SDL_ClearError(void)
   194 void SDL_ClearError(void)
   280 {
   195 {
   281 	SDL_error *error;
   196 	SDL_error *error;