stdinc: Drastically improve SDL_StepUTF8() and make it a public API.

Fixes #10105.
This commit is contained in:
Ryan C. Gordon
2024-06-26 21:32:45 -04:00
parent 9b8c5f642f
commit a9cfcf6bde
8 changed files with 211 additions and 58 deletions

View File

@@ -10,13 +10,6 @@
freely.
*/
/* quiet windows compiler warnings */
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
@@ -33,6 +26,34 @@ widelen(char *data)
return len;
}
static char *get_next_line(Uint8 **fdataptr, size_t *fdatalen)
{
char *retval = (char *) *fdataptr;
Uint8 *ptr = *fdataptr;
size_t len = *fdatalen;
if (len == 0) {
return NULL;
}
while (len > 0) {
if (*ptr == '\r') {
*ptr = '\0';
} else if (*ptr == '\n') {
*ptr = '\0';
ptr++;
len--;
break;
}
ptr++;
len--;
}
*fdataptr = ptr;
*fdatalen = len;
return retval;
}
int main(int argc, char *argv[])
{
const char *formats[] = {
@@ -51,13 +72,15 @@ int main(int argc, char *argv[])
};
char *fname = NULL;
char buffer[BUFSIZ];
char *ucs4;
char *test[2];
int i;
FILE *file;
int errors = 0;
SDLTest_CommonState *state;
Uint8 *fdata = NULL;
Uint8 *fdataptr = NULL;
char *line = NULL;
size_t fdatalen = 0;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
@@ -89,20 +112,19 @@ int main(int argc, char *argv[])
}
fname = GetResourceFilename(fname, "utf8.txt");
file = fopen(fname, "rb");
if (!file) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", fname);
fdata = (Uint8 *) (fname ? SDL_LoadFile(fname, &fdatalen) : NULL);
if (!fdata) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to load %s\n", fname);
return 1;
}
SDL_free(fname);
while (fgets(buffer, sizeof(buffer), file)) {
fdataptr = fdata;
while ((line = get_next_line(&fdataptr, &fdatalen)) != NULL) {
/* Convert to UCS-4 */
size_t len;
ucs4 =
SDL_iconv_string("UCS-4", "UTF-8", buffer,
SDL_strlen(buffer) + 1);
ucs4 = SDL_iconv_string("UCS-4", "UTF-8", line, SDL_strlen(line) + 1);
len = (widelen(ucs4) + 1) * 4;
for (i = 0; i < SDL_arraysize(formats); ++i) {
test[0] = SDL_iconv_string(formats[i], "UCS-4", ucs4, len);
test[1] = SDL_iconv_string("UCS-4", formats[i], test[0], len);
@@ -115,10 +137,44 @@ int main(int argc, char *argv[])
}
test[0] = SDL_iconv_string("UTF-8", "UCS-4", ucs4, len);
SDL_free(ucs4);
(void)fputs(test[0], stdout);
SDL_Log("%s", test[0]);
SDL_free(test[0]);
}
(void)fclose(file);
SDL_free(fdata);
#if 0
{
Uint32 *ucs4buf;
Uint32 *ucs4ptr;
char *utf8out;
Uint32 cp;
SDL_IOStream *io;
fdata = (Uint8 *) (fname ? SDL_LoadFile(fname, &fdatalen) : NULL);
if (!fdata) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to load %s\n", fname);
return 1;
}
ucs4buf = (Uint32 *) SDL_malloc(fdatalen * 4);
ucs4ptr = ucs4buf;
fdataptr = fdata;
while ((cp = SDL_StepUTF8((const char **) &fdataptr, &fdatalen)) != 0) {
*(ucs4ptr++) = SDL_Swap32BE(cp);
}
*(ucs4ptr++) = 0;
utf8out = SDL_iconv_string("UTF-8", "UCS-4", (const char *) ucs4buf, (size_t) ((ucs4ptr - ucs4buf)) * 4);
io = SDL_IOFromFile("test_steputf8.txt", "wb");
SDL_WriteIO(io, utf8out, SDL_strlen(utf8out));
SDL_CloseIO(io);
SDL_free(ucs4buf);
SDL_free(utf8out);
SDL_free(fdata);
}
#endif
SDL_free(fname);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Total errors: %d\n", errors);
SDL_Quit();