uppercasing now faster and safer

This commit is contained in:
Albert Cahalan 2008-05-29 07:02:45 +00:00
parent 1093d74230
commit 2687b4efd1

View file

@ -1468,8 +1468,8 @@ static void print_image(void);
static void do_print(void); static void do_print(void);
static void strip_trailing_whitespace(char *buf); static void strip_trailing_whitespace(char *buf);
static void do_render_cur_text(int do_blit); static void do_render_cur_text(int do_blit);
static char *uppercase(char *str); static char *uppercase(const char *restrict const str);
static wchar_t *uppercase_w(wchar_t * str); static wchar_t *uppercase_w(const wchar_t *restrict const str);
static char *textdir(const char *const str); static char *textdir(const char *const str);
static SDL_Surface *do_render_button_label(const char *const label); static SDL_Surface *do_render_button_label(const char *const label);
static void create_button_labels(void); static void create_button_labels(void);
@ -15280,88 +15280,72 @@ static void do_render_cur_text(int do_blit)
#ifdef OLD_UPPERCASE_CODE #ifdef OLD_UPPERCASE_CODE
static char *uppercase(char *str) static char *uppercase(const char *restrict const str)
{ {
char *ustr; char *ustr = strdup(str);
int i;
ustr = strdup(str);
if (only_uppercase) if (only_uppercase)
{ {
for (i = 0; i < strlen(ustr); i++) unsigned i = 0;
do{
ustr[i] = toupper(ustr[i]); ustr[i] = toupper(ustr[i]);
while(ustr[i++]);
} }
#ifdef DEBUG #ifdef DEBUG
printf(" ORIGINAL: %s\n" "UPPERCASE: %s\n\n", str, ustr); printf(" ORIGINAL: %s\n" "UPPERCASE: %s\n\n", str, ustr);
#endif #endif
return (ustr); return ustr;
} }
#else #else
static char *uppercase(char *str) static char *uppercase(const char *restrict const str)
{ {
unsigned int i, sz; unsigned int i, n;
wchar_t *dest; wchar_t *dest;
char *ustr; char *ustr;
if (only_uppercase) if (!only_uppercase)
{ return strdup(str);
sz = sizeof(wchar_t) * (strlen(str) + 1);
dest = (wchar_t *) malloc(sz); // watch out: uppercase chars may need extra bytes!
// FIXME: uppercase chars may need extra bytes // http://en.wikipedia.org/wiki/Turkish_dotted_and_dotless_I
ustr = malloc(strlen(str) + 1); n = strlen(str) + 1;
dest = alloca(sizeof(wchar_t)*n);
ustr = malloc(n*2); // use *2 in case 'i' becomes U+0131
if (dest != NULL) mbstowcs(dest, str, sizeof(wchar_t)*n); // at most n wchar_t written
{ i = 0;
mbstowcs(dest, str, sz); do{
dest[i] = towupper(dest[i]);
for (i = 0; i < strlen(str); i++) }while(dest[i++]);
{ wcstombs(ustr, dest, n); // at most n bytes written
dest[i] = towupper(dest[i]);
}
wcstombs(ustr, dest, sizeof(char) * (strlen(str) + 1));
free(dest);
}
#ifdef DEBUG #ifdef DEBUG
printf(" ORIGINAL: %s\n" "UPPERCASE: %s\n\n", str, ustr); printf(" ORIGINAL: %s\n" "UPPERCASE: %s\n\n", str, ustr);
#endif #endif
} return ustr;
else
{
ustr = strdup(str);
}
return (ustr);
} }
#endif #endif
static wchar_t *uppercase_w(wchar_t * str) static wchar_t *uppercase_w(const wchar_t *restrict const str)
{ {
wchar_t *ustr; unsigned n = wcslen(str) + 1;
unsigned int i; wchar_t *ustr = malloc(sizeof(wchar_t) * n);
memcpy(ustr,str,sizeof(wchar_t) * n);
ustr = (wchar_t *) malloc(sizeof(wchar_t) * (wcslen(str) + 1)); if (only_uppercase)
if (ustr != NULL)
{ {
wcscpy(ustr, str); unsigned i = 0;
if (only_uppercase) do{
{ ustr[i] = towupper(ustr[i]);
for (i = 0; i < wcslen(ustr); i++) }while(ustr[i++]);
ustr[i] = towupper(ustr[i]);
}
} }
return (ustr); return ustr;
} }