diff --git a/test/meson.build b/test/meson.build index 58f0ec9c..20c6bddb 100644 --- a/test/meson.build +++ b/test/meson.build @@ -31,6 +31,7 @@ endif libui_test_sources_without_cases = [ 'errors.c', 'main.c', + 'utf8.c', ] if libui_OS == 'windows' libui_test_sources_without_cases += [ diff --git a/test/test.h b/test/test.h index 39cfc521..4e9786c3 100644 --- a/test/test.h +++ b/test/test.h @@ -87,6 +87,19 @@ extern void endCheckProgrammerErrorFull(const char *file, long line, void *conte extern void testControlLoadNopVtable(uiControlVtable *vtable); extern const uiControlOSVtable *testOSVtable(void); +// utf8.c +extern const char testUTF8Empty[]; +extern const char testUTF8ASCIIOnly[]; +extern const char testUTF8WithTwoByte[]; +extern const char testUTF8WithThreeByte[]; +extern const char testUTF8WithFourByte[]; +extern const char testUTF8Combined[]; +extern const char testUTF8InvalidInput[]; +extern const char testUTF8InvalidOutput[]; +extern bool utf8equal(const char *s, const char *t); +extern void utf8diffErrorfFull(const char *file, long line, const char *msg, const char *got, const char *want); +#define utf8diffErrorf(msg, got, want) utf8diffErrorfFull(__FILE__, __LINE__, msg, got, want) + #ifdef __cplusplus } #endif diff --git a/test/utf8.c b/test/utf8.c index 1904bd3f..62153265 100644 --- a/test/utf8.c +++ b/test/utf8.c @@ -3,7 +3,8 @@ // Do not put any test cases in this file; they will not be run. -/* C99 notes on the safety of storing UTF-8 data directly in char: +/* TODO address all this +C99 notes on the safety of storing UTF-8 data directly in char: - §5.2.4.2.1¶1 says char, signed char, and unsigned char must be no fewer than 8 bits wide - §6.2.5¶15 states that char must either be signed char or unsigned char (or some equivalent) - footnote 35 says that CHAR_MIN can be used to detect which one was chosen, which can help in some of the situations below @@ -58,4 +59,35 @@ bool utf8equal(const char *s, const char *t) } } -// TODO utf8diff +static void utf8hexdump(char buf[64], const char *s) +{ + int i; + uint8_t x; + + for (i = 0; i < 60; i += 3) { + x = (uint8_t) (*s); + s++; + buf[i + 0] = "0123456789ABCDEF"[(x & 0xF0) >> 4]; + buf[i + 1] = "0123456789ABCDEF"[x & 0x0F]; + if (x == 0) { + buf[i + 2] = '\0'; + break; + } + buf[i + 2] = ' '; + } + if (i >= 60) { + buf[60] = '.'; + buf[61] = '.'; + buf[62] = '.'; + buf[63] = '\0'; + } +} + +void utf8diffErrorfFull(const char *file, long line, const char *msg, const char *got, const char *want) +{ + char a[64], b[64]; + + utf8hexdump(a, got); + utf8hexdump(b, want); + TestErrorfFull(file, line, "%s:" diff("%s"), msg, a, b); +}