This function has a bit more overhead than most error functions so that it supports internationalization and thread-safe errors. */
| 193 | so that it supports internationalization and thread-safe errors. |
| 194 | */ |
| 195 | static char * |
| 196 | SDL_GetErrorMsg(char *errstr, int maxlen) |
| 197 | { |
| 198 | SDL_error *error; |
| 199 | |
| 200 | /* Clear the error string */ |
| 201 | *errstr = '\0'; |
| 202 | --maxlen; |
| 203 | |
| 204 | /* Get the thread-safe error, and print it out */ |
| 205 | error = SDL_GetErrBuf(); |
| 206 | if (error->error) { |
| 207 | const char *fmt; |
| 208 | char *msg = errstr; |
| 209 | int len; |
| 210 | int argi; |
| 211 | |
| 212 | fmt = SDL_LookupString(error->key); |
| 213 | argi = 0; |
| 214 | while (*fmt && (maxlen > 0)) { |
| 215 | if (*fmt == '%') { |
| 216 | char tmp[32], *spot = tmp; |
| 217 | *spot++ = *fmt++; |
| 218 | while ((*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) |
| 219 | && spot < (tmp + SDL_arraysize(tmp) - 2)) { |
| 220 | *spot++ = *fmt++; |
| 221 | } |
| 222 | if (*fmt == 'l') { |
| 223 | *spot++ = *fmt++; |
| 224 | *spot++ = *fmt++; |
| 225 | *spot++ = '\0'; |
| 226 | switch (spot[-2]) { |
| 227 | case 'i': case 'd': case 'u': case 'x': case 'X': |
| 228 | len = SDL_snprintf(msg, maxlen, tmp, |
| 229 | error->args[argi++].value_l); |
| 230 | if (len > 0) { |
| 231 | msg += len; |
| 232 | maxlen -= len; |
| 233 | } |
| 234 | break; |
| 235 | } |
| 236 | continue; |
| 237 | } |
| 238 | *spot++ = *fmt++; |
| 239 | *spot++ = '\0'; |
| 240 | switch (spot[-2]) { |
| 241 | case '%': |
| 242 | *msg++ = '%'; |
| 243 | maxlen -= 1; |
| 244 | break; |
| 245 | case 'c': |
| 246 | case 'i': |
| 247 | case 'd': |
| 248 | case 'u': |
| 249 | case 'o': |
| 250 | case 'x': |
| 251 | case 'X': |
| 252 | len = |
no test coverage detected