637 lines
33 KiB
C
637 lines
33 KiB
C
// SPDX-FileCopyrightText: 2025 Rot127 <rot127@posteo.com>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include <rz_util.h>
|
|
#include "minunit.h"
|
|
#include <rz_util/rz_unicode.h>
|
|
#include <rz_util/rz_utf32.h>
|
|
#include <rz_util/rz_ebcdic.h>
|
|
#include <rz_util/rz_utf8.h>
|
|
|
|
bool test_rz_utf8_decode(void) {
|
|
RzCodePoint codepoint = 0;
|
|
const ut8 utf8_1b_valid_first[] = { 0x00 };
|
|
const ut8 utf8_1b_valid_last[] = { 0x7f };
|
|
const ut8 utf8_2b_valid_first[] = { 0xC2, 0x80 };
|
|
const ut8 utf8_2b_valid_last[] = { 0xDF, 0xBF };
|
|
const ut8 utf8_3b_valid_first[] = { 0xE0, 0xA0, 0x80 };
|
|
const ut8 utf8_3b_valid_last[] = { 0xEF, 0xBF, 0xBD };
|
|
const ut8 utf8_4b_valid_first[] = { 0xF0, 0x90, 0x80, 0x80 };
|
|
const ut8 utf8_4b_valid_last[] = { 0xF4, 0x8F, 0xBF, 0xBD };
|
|
|
|
mu_assert_eq(rz_utf8_decode(utf8_1b_valid_first, sizeof(utf8_1b_valid_first), &codepoint, true), 1, "Decode failed");
|
|
mu_assert_eq(codepoint, 0, "Code point incorrect");
|
|
mu_assert_eq(rz_utf8_decode(utf8_1b_valid_last, sizeof(utf8_1b_valid_last), &codepoint, true), 1, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x7f, "Code point incorrect");
|
|
|
|
mu_assert_eq(rz_utf8_decode(utf8_2b_valid_first, sizeof(utf8_2b_valid_first), &codepoint, true), 2, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x80, "Code point incorrect");
|
|
mu_assert_eq(rz_utf8_decode(utf8_2b_valid_last, sizeof(utf8_2b_valid_last), &codepoint, true), 2, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x07FF, "Code point incorrect");
|
|
|
|
mu_assert_eq(rz_utf8_decode(utf8_3b_valid_first, sizeof(utf8_3b_valid_first), &codepoint, true), 3, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x800, "Code point incorrect");
|
|
mu_assert_eq(rz_utf8_decode(utf8_3b_valid_last, sizeof(utf8_3b_valid_last), &codepoint, true), 3, "Decode failed");
|
|
mu_assert_eq(codepoint, 0xFFFD, "Code point incorrect");
|
|
|
|
mu_assert_eq(rz_utf8_decode(utf8_4b_valid_first, sizeof(utf8_4b_valid_first), &codepoint, true), 4, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x10000, "Code point incorrect");
|
|
mu_assert_eq(rz_utf8_decode(utf8_4b_valid_last, sizeof(utf8_4b_valid_last), &codepoint, true), 4, "Decode failed");
|
|
mu_assert_eq(codepoint, 0x10FFFD, "Code point incorrect");
|
|
|
|
const ut8 utf8_1b_invalid_F[] = { 0xFF };
|
|
const ut8 utf8_2b_invalid_F[] = { 0xFF, 0x00 };
|
|
const ut8 utf8_3b_invalid_F[] = { 0xFF, 0x00, 0x00 };
|
|
mu_assert_eq(rz_utf8_decode(utf8_1b_invalid_F, sizeof(utf8_1b_invalid_F), &codepoint, true), 0, "Invalid decode, prefix bit false.");
|
|
mu_assert_eq(rz_utf8_decode(utf8_2b_invalid_F, sizeof(utf8_2b_invalid_F), &codepoint, true), 0, "Invalid decode, prefix bit false.");
|
|
mu_assert_eq(rz_utf8_decode(utf8_3b_invalid_F, sizeof(utf8_3b_invalid_F), &codepoint, true), 0, "Invalid decode, prefix bit false.");
|
|
|
|
const ut8 utf8_2b_invalid_small_code_point[] = { 0xC0, 0x80 };
|
|
const ut8 utf8_3b_invalid_small_code_point[] = { 0xE0, 0x80, 0x80 };
|
|
const ut8 utf8_4b_invalid_small_code_point[] = { 0xF0, 0x80, 0x80, 0x80 };
|
|
|
|
mu_assert_eq(rz_utf8_decode(utf8_2b_invalid_small_code_point, sizeof(utf8_2b_invalid_small_code_point), &codepoint, true), 0, "Invalid decode, code point is too small for encoding.");
|
|
mu_assert_eq(rz_utf8_decode(utf8_3b_invalid_small_code_point, sizeof(utf8_3b_invalid_small_code_point), &codepoint, true), 0, "Invalid decode, code point is too small for encoding.");
|
|
mu_assert_eq(rz_utf8_decode(utf8_4b_invalid_small_code_point, sizeof(utf8_4b_invalid_small_code_point), &codepoint, true), 0, "Invalid decode, code point is too small for encoding.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
/**
|
|
* \brief Examples partially taken from: https://en.wikipedia.org/wiki/UTF-16#Examples
|
|
*/
|
|
bool test_rz_utf16_decode(void) {
|
|
RzCodePoint codepoint = 0;
|
|
const ut8 utf16le_surrogate[] = { 0xd8, 0x00 };
|
|
mu_assert_eq(rz_utf16_decode(utf16le_surrogate, 2, &codepoint, true, true), 0, "Invalid decode");
|
|
|
|
char utf8_out[5] = { 0 };
|
|
const ut8 utf16le_A[] = { 0x41, 0x00 };
|
|
const ut8 utf16be_A[] = { 0x00, 0x41 };
|
|
|
|
int nbytes = rz_utf16_decode(utf16le_A, 2, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x0041, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "A", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
nbytes = rz_utf16_decode(utf16be_A, 2, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x0041, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "A", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
const ut8 utf16le[] = { 0xAC, 0x20 };
|
|
const ut8 utf16be[] = { 0x20, 0xAC };
|
|
|
|
nbytes = rz_utf16_decode(utf16le, 2, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x20AC, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "€", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
nbytes = rz_utf16_decode(utf16be, 2, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x20AC, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "€", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
// With surrogate
|
|
const ut8 utf16le_surr[] = { 0x01, 0xD8, 0x37, 0xDC };
|
|
const ut8 utf16be_surr[] = { 0xD8, 0x01, 0xDC, 0x37 };
|
|
|
|
nbytes = rz_utf16_decode(utf16le_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x10437, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "𐐷", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
nbytes = rz_utf16_decode(utf16be_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x10437, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "𐐷", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
const ut8 utf16le_first_surr[] = { 0x00, 0xD8, 0x00, 0xDC };
|
|
const ut8 utf16be_first_surr[] = { 0xD8, 0x00, 0xDC, 0x00 };
|
|
|
|
nbytes = rz_utf16_decode(utf16le_first_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x10000, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "𐀀", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
nbytes = rz_utf16_decode(utf16be_first_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0x10000, "Character decode failed.", "0x%" PFMT64x);
|
|
rz_utf8_encode((ut8 *)utf8_out, codepoint);
|
|
mu_assert_streq(utf8_out, "𐀀", "Encode failed.");
|
|
memset(utf8_out, 0, sizeof(utf8_out));
|
|
|
|
const ut8 utf16le_last_surr[] = { 0xFF, 0xDB, 0xFF, 0xDF };
|
|
const ut8 utf16be_last_surr[] = { 0xDB, 0xFF, 0xDF, 0xFF };
|
|
|
|
nbytes = rz_utf16_decode(utf16le_last_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
|
|
nbytes = rz_utf16_decode(utf16be_last_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
|
|
nbytes = rz_utf16_decode(utf16be_last_surr, 2, &codepoint, false, true);
|
|
mu_assert_eq(nbytes, 0, "Surrogate should never be allowed.");
|
|
const ut8 utf16_undef[] = { 0xFF, 0xFF };
|
|
nbytes = rz_utf16_decode(utf16_undef, 2, &codepoint, false, true);
|
|
mu_assert_eq(nbytes, 2, "Undefined was allowed.");
|
|
|
|
const ut8 utf16le_invalid_small_surr[] = { 0x00, 0xD7, 0x00, 0xDB };
|
|
const ut8 utf16be_invalid_small_surr[] = { 0xD7, 0x00, 0xDB, 0x00 };
|
|
|
|
// Fails to decode 4, should decode 2 bytes.
|
|
nbytes = rz_utf16_decode(utf16le_invalid_small_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0xD700, "Character decode failed.", "0x%" PFMT64x);
|
|
|
|
nbytes = rz_utf16_decode(utf16be_invalid_small_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_eq_fmt(codepoint, 0xD700, "Character decode failed.", "0x%" PFMT64x);
|
|
|
|
const ut8 utf16le_invalid_big_surr[] = { 0x01, 0xDC, 0x37, 0xE0 };
|
|
const ut8 utf16be_invalid_big_surr[] = { 0xDC, 0x01, 0xE0, 0x37 };
|
|
|
|
nbytes = rz_utf16_decode(utf16le_invalid_big_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
nbytes = rz_utf16_decode(utf16be_invalid_big_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
|
|
const ut8 utf16le_last_non_surr[] = { 0xff, 0xff, 0xff, 0xff };
|
|
const ut8 utf16be_last_non_surr[] = { 0xff, 0xff, 0xff, 0xff };
|
|
|
|
nbytes = rz_utf16_decode(utf16le_last_non_surr, 4, &codepoint, true, false);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
nbytes = rz_utf16_decode(utf16be_last_non_surr, 4, &codepoint, true, true);
|
|
mu_assert_eq(nbytes, 0, "Undefined code point.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
/**
|
|
* \brief Examples partially taken from: https://en.wikipedia.org/wiki/UTF-16#Examples
|
|
*/
|
|
bool test_rz_utf16_encode(void) {
|
|
ut8 utf16_out[5] = { 0 };
|
|
|
|
const ut8 utf16le[] = { 0xAC, 0x20 };
|
|
const ut8 utf16be[] = { 0x20, 0xAC };
|
|
RzCodePoint codepoint = 0x20AC;
|
|
int nbytes = rz_utf16_encode(utf16_out, codepoint, false);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16le, sizeof(utf16le), "Encode failed.");
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, true);
|
|
mu_assert_eq(nbytes, 2, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16be, sizeof(utf16be), "Encode failed.");
|
|
memset(utf16_out, 0, sizeof(utf16_out));
|
|
|
|
// With surrogate
|
|
const ut8 utf16le_surr[] = { 0x01, 0xD8, 0x37, 0xDC };
|
|
const ut8 utf16be_surr[] = { 0xD8, 0x01, 0xDC, 0x37 };
|
|
codepoint = 0x10437;
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, false);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16le_surr, sizeof(utf16le), "Encode failed.");
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, true);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16be_surr, sizeof(utf16be_surr), "Encode failed.");
|
|
memset(utf16_out, 0, sizeof(utf16_out));
|
|
|
|
const ut8 utf16le_first_surr[] = { 0x00, 0xD8, 0x00, 0xDC };
|
|
const ut8 utf16be_first_surr[] = { 0xD8, 0x00, 0xDC, 0x00 };
|
|
codepoint = 0x10000;
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, false);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16le_first_surr, sizeof(utf16le_first_surr), "Encode failed.");
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, true);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16be_first_surr, sizeof(utf16be_first_surr), "Encode failed.");
|
|
memset(utf16_out, 0, sizeof(utf16_out));
|
|
|
|
const ut8 utf16le_last_surr[] = { 0xFF, 0xDB, 0xFF, 0xDF };
|
|
const ut8 utf16be_last_surr[] = { 0xDB, 0xFF, 0xDF, 0xFF };
|
|
codepoint = RZ_UNICODE_LAST_CODE_POINT;
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, false);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16le_last_surr, sizeof(utf16le_last_surr), "Encode failed.");
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, true);
|
|
mu_assert_eq(nbytes, 4, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, utf16be_last_surr, sizeof(utf16be_last_surr), "Encode failed.");
|
|
|
|
memset(utf16_out, 0, sizeof(utf16_out));
|
|
|
|
ut8 zero[5] = { 0 };
|
|
codepoint = 0x110000;
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, false);
|
|
mu_assert_eq(nbytes, 0, "Decoded number of bytes mismatch.");
|
|
nbytes = rz_utf16_encode(utf16_out, codepoint, true);
|
|
mu_assert_eq(nbytes, 0, "Decoded number of bytes mismatch.");
|
|
mu_assert_memeq(utf16_out, zero, sizeof(zero), "Encode failed.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_utf32_decode(void) {
|
|
const ut8 utf32_size_1[] = { 0xAC };
|
|
const ut8 utf32_size_2[] = { 0xAC, 0xAC };
|
|
const ut8 utf32_size_3[] = { 0xAC, 0xAC, 0x20 };
|
|
const ut8 utf32_undefined_I[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
const ut8 utf32_invalid_surrogate[] = { 0x00, 0x00, 0xD8, 0x00 };
|
|
|
|
const ut8 utf32be_A[] = { 0x00, 0x00, 0x00, 0x41 };
|
|
const ut8 utf32le_A[] = { 0x41, 0x00, 0x00, 0x00 };
|
|
|
|
// The non-ascii small a
|
|
const ut8 utf32be_a[] = { 0x00, 0x00, 0xff, 0x41 };
|
|
const ut8 utf32le_a[] = { 0x41, 0xff, 0x00, 0x00 };
|
|
|
|
// Chess tower symbol Red General: 🩠
|
|
const ut8 utf32be_red_general[] = { 0x00, 0x01, 0xFA, 0x60 };
|
|
const ut8 utf32le_red_general[] = { 0x60, 0xfa, 0x01, 0x00 };
|
|
|
|
// Chess tower symbol Red General: 🩠 🩁
|
|
const ut8 utf32be_red_general_black_tower[] = { 0x00, 0x01, 0xFA, 0x60, 0x00, 0x01, 0xFA, 0x41 };
|
|
const ut8 utf32le_red_general_black_tower[] = { 0x60, 0xFA, 0x01, 0x00, 0x41, 0xFA, 0x01, 0x00 };
|
|
|
|
RzCodePoint cp;
|
|
mu_assert_eq(rz_utf32_decode((ut8 *)INT_MIN, 0, &cp, true, false), 0, "Length check failed");
|
|
mu_assert_eq(rz_utf32_decode(utf32_size_1, sizeof(utf32_size_1), &cp, true, false), 0, "Length check failed");
|
|
mu_assert_eq(rz_utf32_decode(utf32_size_2, sizeof(utf32_size_2), &cp, true, false), 0, "Length check failed");
|
|
mu_assert_eq(rz_utf32_decode(utf32_size_3, sizeof(utf32_size_3), &cp, true, false), 0, "Length check failed");
|
|
mu_assert_eq(rz_utf32_decode(utf32_undefined_I, sizeof(utf32_undefined_I), &cp, true, false), 0, "Undefined");
|
|
mu_assert_eq(rz_utf32_decode(utf32_undefined_I, sizeof(utf32_undefined_I), &cp, false, false), 4, "Undefined was allowed");
|
|
mu_assert_eq(rz_utf32_decode(utf32_invalid_surrogate, sizeof(utf32_invalid_surrogate), &cp, true, false), 0, "Undefined");
|
|
|
|
mu_assert_eq(rz_utf32_decode(utf32be_A, sizeof(utf32be_A), &cp, true, true), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x41, "Incorrect decoding.");
|
|
mu_assert_eq(rz_utf32_decode(utf32le_A, sizeof(utf32le_A), &cp, true, false), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x41, "Incorrect decoding.");
|
|
|
|
mu_assert_eq(rz_utf32_decode(utf32be_a, sizeof(utf32be_a), &cp, true, true), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0xff41, "Incorrect decoding.");
|
|
mu_assert_eq(rz_utf32_decode(utf32le_a, sizeof(utf32le_a), &cp, true, false), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0xff41, "Incorrect decoding.");
|
|
|
|
mu_assert_eq(rz_utf32_decode(utf32be_red_general, sizeof(utf32be_red_general), &cp, true, true), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa60, "Incorrect decoding.");
|
|
mu_assert_eq(rz_utf32_decode(utf32le_red_general, sizeof(utf32le_red_general), &cp, true, false), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa60, "Incorrect decoding.");
|
|
|
|
mu_assert_eq(rz_utf32_decode(utf32be_red_general_black_tower, sizeof(utf32be_red_general_black_tower), &cp, true, true), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa60, "Incorrect decoding.");
|
|
mu_assert_eq(rz_utf32_decode(utf32le_red_general_black_tower, sizeof(utf32le_red_general_black_tower), &cp, true, false), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa60, "Incorrect decoding.");
|
|
|
|
mu_assert_eq(rz_utf32_decode(utf32be_red_general_black_tower + 4, sizeof(utf32be_red_general_black_tower) - 4, &cp, true, true), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa41, "Incorrect decoding.");
|
|
mu_assert_eq(rz_utf32_decode(utf32le_red_general_black_tower + 4, sizeof(utf32le_red_general_black_tower) - 4, &cp, true, false), 4, "Length check failed");
|
|
mu_assert_eq(cp, 0x01fa41, "Incorrect decoding.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_utf32_valid(void) {
|
|
const ut8 utf32le_invalid_size[] = { 0xAC, 0xAC, 0x20 };
|
|
|
|
const ut8 utf32be_valid_max_cp[] = { 0x00, 0x10, 0xff, 0xff };
|
|
const ut8 utf32be_invalid_max_cp[] = { 0x00, 0x11, 0x00, 0x00 };
|
|
|
|
const ut8 utf32le_valid_max_cp[] = { 0xff, 0xff, 0x10, 0x00 };
|
|
const ut8 utf32le_invalid_max_cp[] = { 0x00, 0x00, 0x11, 0x00 };
|
|
|
|
const ut8 utf32be_invalid_surrogate_I[] = { 0x00, 0x00, 0xd8, 0x00 };
|
|
const ut8 utf32be_invalid_surrogate_II[] = { 0x00, 0x00, 0xdf, 0xff };
|
|
const ut8 utf32be_invalid_surrogate_III[] = { 0x00, 0x00, 0xd7, 0xff };
|
|
const ut8 utf32be_invalid_surrogate_IV[] = { 0x00, 0x00, 0xe0, 0x00 };
|
|
|
|
const ut8 utf32be_valid_invalid[] = { 0x00, 0x10, 0xff, 0xff, 0x00, 0x11, 0x00, 0x00 };
|
|
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32le_invalid_size, sizeof(utf32le_invalid_size), false, 1), "Length check failed");
|
|
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_invalid_max_cp, sizeof(utf32be_invalid_max_cp), true, 1), "Invalid max failed");
|
|
mu_assert_true(rz_utf32_valid_code_point(utf32be_valid_max_cp, sizeof(utf32be_valid_max_cp), true, 1), "Valid max failed");
|
|
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32le_invalid_max_cp, sizeof(utf32le_invalid_max_cp), false, 1), "Invalid max failed");
|
|
mu_assert_true(rz_utf32_valid_code_point(utf32le_valid_max_cp, sizeof(utf32le_valid_max_cp), false, 1), "Valid max failed");
|
|
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_invalid_surrogate_I, sizeof(utf32be_invalid_surrogate_I), true, 1), "Surrogate failed");
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_invalid_surrogate_II, sizeof(utf32be_invalid_surrogate_II), true, 1), "Surrogate failed");
|
|
mu_assert_true(rz_utf32_valid_code_point(utf32be_invalid_surrogate_III, sizeof(utf32be_invalid_surrogate_III), true, 1), "Surrogate failed");
|
|
mu_assert_true(rz_utf32_valid_code_point(utf32be_invalid_surrogate_IV, sizeof(utf32be_invalid_surrogate_IV), true, 1), "Surrogate failed");
|
|
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_invalid_surrogate_IV, sizeof(utf32be_invalid_surrogate_IV), true, 2), "Look ahead is not covered by buffer.");
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_invalid_surrogate_IV, sizeof(utf32be_invalid_surrogate_IV), true, 0), "Look ahead is 0.");
|
|
|
|
mu_assert_true(rz_utf32_valid_code_point(utf32be_valid_invalid, sizeof(utf32be_valid_invalid), true, 1), "First is ok.");
|
|
mu_assert_false(rz_utf32_valid_code_point(utf32be_valid_invalid, sizeof(utf32be_valid_invalid), true, 2), "But last one is not ok.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_ebcdic_valid(void) {
|
|
// General
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0x41), "A should be valid.");
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0), "\\0 should be valid.");
|
|
// EBCDIC-ES
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0xf1), "ñ should be valid.");
|
|
// EBCDIC-US
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0xa2), "¢ should be valid.");
|
|
// EBCDIC-UK
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0xa3), "£ should be valid.");
|
|
// IBM037
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0xe4), "ä should be valid.");
|
|
// IBM290
|
|
mu_assert_true(rz_str_ebcdic_valid_code_point(0x30a5), "ゥshould be valid.");
|
|
|
|
// An unsopported one.
|
|
mu_assert_false(rz_str_ebcdic_valid_code_point(0x1E4E), "Ṏ should not be valid.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_printable(void) {
|
|
// Control
|
|
mu_assert_false(rz_unicode_code_point_is_printable(0x0), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(31), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(32), "Printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(126), "Printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(127), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(159), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(160), "Printable.");
|
|
|
|
// Surrogates
|
|
mu_assert_false(rz_unicode_code_point_is_printable(55296), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(57343), "Not printable.");
|
|
|
|
// Private - consider them not printable
|
|
mu_assert_false(rz_unicode_code_point_is_printable(57344), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(63743), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(63744), "Printable.");
|
|
|
|
mu_assert_false(rz_unicode_code_point_is_printable(983040), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(1048573), "Not printable.");
|
|
|
|
mu_assert_false(rz_unicode_code_point_is_printable(1048576), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(1114109), "Not printable.");
|
|
|
|
// Undefined
|
|
// First
|
|
mu_assert_true(rz_unicode_code_point_is_printable(887), "Printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(888), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(889), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(890), "Printable.");
|
|
// Last
|
|
mu_assert_false(rz_unicode_code_point_is_printable(1114110), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(1114111), "Not printable.");
|
|
// Out of code point range.
|
|
mu_assert_false(rz_unicode_code_point_is_printable(0x110000), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(0xFFFFFFFF), "Not printable.");
|
|
// Even offset in table
|
|
mu_assert_true(rz_unicode_code_point_is_printable(3010), "Printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(3011), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(3013), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(3014), "Printable.");
|
|
// Odd offset in table
|
|
mu_assert_true(rz_unicode_code_point_is_printable(3016), "Printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(3017), "Not printable.");
|
|
mu_assert_true(rz_unicode_code_point_is_printable(3018), "Printable.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_control(void) {
|
|
// Control
|
|
mu_assert_true(rz_unicode_code_point_is_control(0x0), "Control.");
|
|
mu_assert_true(rz_unicode_code_point_is_control(31), "Control.");
|
|
mu_assert_false(rz_unicode_code_point_is_control(32), "Not control.");
|
|
mu_assert_false(rz_unicode_code_point_is_control(126), "Not control.");
|
|
mu_assert_true(rz_unicode_code_point_is_control(127), "Control.");
|
|
mu_assert_true(rz_unicode_code_point_is_control(159), "Control.");
|
|
mu_assert_false(rz_unicode_code_point_is_control(160), "Not control.");
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_surrogate(void) {
|
|
// Surrogates
|
|
mu_assert_false(rz_unicode_code_point_is_printable(55296), "Not printable.");
|
|
mu_assert_false(rz_unicode_code_point_is_printable(57343), "Not printable.");
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_private(void) {
|
|
// Private - consider them private
|
|
mu_assert_false(rz_unicode_code_point_is_private(57343), "Not private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(57344), "Private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(63743), "Private.");
|
|
mu_assert_false(rz_unicode_code_point_is_private(63744), "Not private.");
|
|
|
|
mu_assert_false(rz_unicode_code_point_is_private(983039), "Not private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(983040), "Private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(1048573), "Private.");
|
|
mu_assert_false(rz_unicode_code_point_is_private(1048574), "Not private.");
|
|
|
|
mu_assert_false(rz_unicode_code_point_is_private(1048575), "Not private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(1048576), "Private.");
|
|
mu_assert_true(rz_unicode_code_point_is_private(1114109), "Private.");
|
|
mu_assert_false(rz_unicode_code_point_is_private(1114110), "Not private.");
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_undefined(void) {
|
|
// Undefined
|
|
// First
|
|
mu_assert_true(rz_unicode_code_point_is_defined(887), "Defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(888), "Not defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(889), "Not defined.");
|
|
mu_assert_true(rz_unicode_code_point_is_defined(890), "Defined.");
|
|
// Last
|
|
mu_assert_true(rz_unicode_code_point_is_defined(1114109), "Defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(1114110), "Not defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(1114111), "Not defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(1114112), "Defined.");
|
|
// Out of range
|
|
mu_assert_false(rz_unicode_code_point_is_defined(0x110000), "Not defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(0xFFFFFFFF), "Not defined.");
|
|
// Even offset in table
|
|
mu_assert_true(rz_unicode_code_point_is_defined(3010), "Defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(3011), "Not defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(3013), "Not defined.");
|
|
mu_assert_true(rz_unicode_code_point_is_defined(3014), "Defined.");
|
|
// Odd offset in table
|
|
mu_assert_true(rz_unicode_code_point_is_defined(3016), "Defined.");
|
|
mu_assert_false(rz_unicode_code_point_is_defined(3017), "Not defined.");
|
|
mu_assert_true(rz_unicode_code_point_is_defined(3018), "Defined.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_utf16_valid(void) {
|
|
const ut8 utf16be_one_byte[] = { 0x00 };
|
|
const ut8 utf16be_A[] = { 0x00, 0x41 };
|
|
const ut8 utf16be_ff[] = { 0x00, 0x00 };
|
|
const ut8 utf16be_EUR[] = { 0x20, 0xAC };
|
|
const ut8 utf16be_complex[] = { 0xD8, 0x01, 0xDC, 0x37 };
|
|
const ut8 utf16be_A_A[] = { 0x00, 0x41, 0x00, 0x41 };
|
|
const ut8 utf16be_complex_EUR_A[] = { 0xD8, 0x01, 0xDC, 0x37, 0x20, 0xAC, 0x00, 0x41 };
|
|
const ut8 utf16be_complex_A_EUR[] = { 0xD8, 0x01, 0xDC, 0x37, 0x00, 0x41, 0x20, 0xAC };
|
|
const ut8 utf16be_A_complex_EUR[] = { 0x00, 0x41, 0xD8, 0x01, 0xDC, 0x37, 0x20, 0xAC };
|
|
const ut8 utf16be_invalid_complex_EUR[] = { 0x00, 0x00, 0xD8, 0x01, 0xDC, 0x37, 0x20, 0xAC };
|
|
const ut8 utf16be_complex_invalid_EUR[] = { 0xD8, 0x01, 0xDC, 0x37, 0x00, 0x00, 0x20, 0xAC };
|
|
const ut8 utf16be_complex_EUR_invalid[] = { 0xD8, 0x01, 0xDC, 0x37, 0x20, 0xAC, 0xD8, 0xff, 0xDC, 0xff };
|
|
|
|
// Simple error cases
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_A, sizeof(utf16be_A), true, 0), "lookahead == 0 is not valid.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_one_byte, sizeof(utf16be_one_byte), false, 1), "Buffer too small.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_ff, sizeof(utf16be_ff), true, 1), "Not printable.");
|
|
|
|
// Simple cases. One character in buffer.
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A, sizeof(utf16be_A), true, 1), "Should be valid");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_EUR, sizeof(utf16be_EUR), true, 1), "Should be valid");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex, sizeof(utf16be_complex), true, 1), "Should be valid");
|
|
|
|
// Different width UTF-16 characters
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_EUR_A, sizeof(utf16be_complex_EUR_A), true, 1), "Should true with 1 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_A_EUR, sizeof(utf16be_complex_A_EUR), true, 1), "Should true with 1 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A_complex_EUR, sizeof(utf16be_A_complex_EUR), true, 1), "Should true with 1 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A_A, sizeof(utf16be_A_A), true, 1), "Should true with 1 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_EUR_A, sizeof(utf16be_complex_EUR_A), true, 2), "Should true with 2 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_A_EUR, sizeof(utf16be_complex_A_EUR), true, 2), "Should true with 2 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A_complex_EUR, sizeof(utf16be_A_complex_EUR), true, 2), "Should true with 2 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A_A, sizeof(utf16be_A_A), true, 2), "Should true with 2 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_EUR_A, sizeof(utf16be_complex_EUR_A), true, 3), "Should true with 3 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_A_EUR, sizeof(utf16be_complex_A_EUR), true, 3), "Should true with 3 different characters.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_A_complex_EUR, sizeof(utf16be_A_complex_EUR), true, 3), "Should true with 3 different characters.");
|
|
|
|
// Look ahead goes past buffer.
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_A, sizeof(utf16be_A), true, 2), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_EUR, sizeof(utf16be_EUR), true, 2), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_complex, sizeof(utf16be_complex), true, 2), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_A_A, sizeof(utf16be_A_A), true, 3), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_complex_EUR_A, sizeof(utf16be_complex_EUR_A), true, 4), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_complex_A_EUR, sizeof(utf16be_complex_A_EUR), true, 4), "Too many code point checks for buffer.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_A_complex_EUR, sizeof(utf16be_A_complex_EUR), true, 4), "Too many code point checks for buffer.");
|
|
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_invalid_complex_EUR, sizeof(utf16be_invalid_complex_EUR), true, 3), "Should fail at first.");
|
|
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_invalid_EUR, sizeof(utf16be_complex_invalid_EUR), true, 1), "The first is still valid.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_complex_invalid_EUR, sizeof(utf16be_complex_invalid_EUR), true, 3), "Should fail before EUR.");
|
|
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_EUR_invalid, sizeof(utf16be_complex_EUR_invalid), true, 1), "The first is still valid.");
|
|
mu_assert_true(rz_utf16_is_printable_code_point(utf16be_complex_EUR_invalid, sizeof(utf16be_complex_EUR_invalid), true, 2), "The second is still valid.");
|
|
mu_assert_false(rz_utf16_is_printable_code_point(utf16be_complex_EUR_invalid, sizeof(utf16be_complex_EUR_invalid), true, 3), "Should be false.");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_lowercase_mapping(void) {
|
|
// first element
|
|
RzUnicodeCaseMapping f = rz_unicode_code_point_find_lower(65);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&f), "Should not be empty");
|
|
mu_assert_eq(f.key, 65, "Mismatched key");
|
|
mu_assert_eq(f.val[0], 97, "Incorrect lowercase value");
|
|
|
|
// multi-value
|
|
RzUnicodeCaseMapping mv = rz_unicode_code_point_find_lower(304);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&mv), "Should not be empty");
|
|
mu_assert_eq(mv.key, 304, "Mismatched key");
|
|
mu_assert_eq(mv.val[0], 105, "Incorrect lowercase value");
|
|
mu_assert_eq(mv.val[1], 775, "Incorrect lowercase value");
|
|
|
|
// last element
|
|
RzUnicodeCaseMapping l = rz_unicode_code_point_find_lower(125217);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&l), "Should not be empty");
|
|
mu_assert_eq(l.key, 125217, "Mismatched key");
|
|
mu_assert_eq(l.val[0], 125251, "Incorrect lowercase value");
|
|
|
|
// not found
|
|
RzUnicodeCaseMapping nf = rz_unicode_code_point_find_lower(0xFFFFFFu);
|
|
mu_assert_eq(nf.key, 0xFFFFFFu, "Mismatched key");
|
|
mu_assert_true(rz_unicode_case_mapping_is_empty(&nf), "Should be empty");
|
|
mu_end;
|
|
}
|
|
|
|
bool test_rz_unicode_uppercase_mapping(void) {
|
|
// first element
|
|
RzUnicodeCaseMapping f = rz_unicode_code_point_find_upper(97);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&f), "Should not be empty");
|
|
mu_assert_eq(f.key, 97, "Mismatched key");
|
|
mu_assert_eq(f.val[0], 65, "Incorrect uppercase value");
|
|
|
|
// multi-value
|
|
RzUnicodeCaseMapping mv = rz_unicode_code_point_find_upper(223);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&mv), "Should not be empty");
|
|
mu_assert_eq(mv.key, 223, "Mismatched key");
|
|
mu_assert_true(mv.val[0] == 83 && mv.val[1] == 83, "Incorrect uppercase value");
|
|
mv = rz_unicode_code_point_find_upper(944);
|
|
mu_assert_eq(mv.key, 944, "Mismatched key");
|
|
mu_assert_true(mv.val[0] == 933 && mv.val[1] == 776 && mv.val[2] == 769, "Incorrect uppercase value");
|
|
|
|
// last element
|
|
RzUnicodeCaseMapping l = rz_unicode_code_point_find_upper(125248);
|
|
mu_assert_false(rz_unicode_case_mapping_is_empty(&l), "Should not be empty");
|
|
mu_assert_eq(l.key, 125248, "Mismatched key");
|
|
mu_assert_eq(l.val[0], 125214, "Incorrect uppercase value");
|
|
|
|
// not found
|
|
RzUnicodeCaseMapping nf = rz_unicode_code_point_find_upper(-1);
|
|
mu_assert_true(rz_unicode_case_mapping_is_empty(&nf), "Should be empty");
|
|
mu_assert_true(nf.key == -1, "Mismatched key");
|
|
mu_end;
|
|
}
|
|
|
|
bool test_utf8_strlen(void) {
|
|
const char *str = "ṡome ⅄ṡ good";
|
|
size_t len = rz_utf8_strlen((const ut8 *)str);
|
|
mu_assert_eq(len, 12, "Should be 12 ucd code points");
|
|
len = rz_utf8_strnlen((const ut8 *)str, 99999999ul);
|
|
mu_assert_eq(len, 12, "Should be 12 ucd code points");
|
|
len = rz_utf8_strnlen((const ut8 *)str, 10);
|
|
mu_assert_eq(len, 6, "Should be 6 ucd code points");
|
|
len = rz_utf8_strnlen((const ut8 *)str, 7);
|
|
mu_assert_eq(len, 5, "Should be 5 ucd code points");
|
|
len = rz_utf8_strnlen((const ut8 *)str, 0);
|
|
mu_assert_eq(len, 0, "Should be 0 ucd code points");
|
|
|
|
// cut a multi-byte character
|
|
len = rz_utf8_strnlen((const ut8 *)str, 9);
|
|
mu_assert_eq(len, 6, "Should be 6 ucd code points");
|
|
len = rz_utf8_strnlen((const ut8 *)str, 8);
|
|
mu_assert_eq(len, 6, "Should be 6 ucd code points");
|
|
|
|
mu_end;
|
|
}
|
|
|
|
bool all_tests() {
|
|
mu_run_test(test_rz_utf8_decode);
|
|
mu_run_test(test_rz_utf16_decode);
|
|
mu_run_test(test_rz_utf16_encode);
|
|
mu_run_test(test_rz_utf32_decode);
|
|
mu_run_test(test_rz_utf32_valid);
|
|
mu_run_test(test_rz_utf16_valid);
|
|
mu_run_test(test_rz_ebcdic_valid);
|
|
mu_run_test(test_rz_unicode_printable);
|
|
mu_run_test(test_rz_unicode_undefined);
|
|
mu_run_test(test_rz_unicode_surrogate);
|
|
mu_run_test(test_rz_unicode_private);
|
|
mu_run_test(test_rz_unicode_control);
|
|
mu_run_test(test_rz_unicode_lowercase_mapping);
|
|
mu_run_test(test_rz_unicode_uppercase_mapping);
|
|
mu_run_test(test_utf8_strlen);
|
|
|
|
return tests_passed != tests_run;
|
|
}
|
|
|
|
mu_main(all_tests)
|