#include #include #include #include "common.h" /* * Testing procedure for from_surrogate_pair and to_surrogate_pair: * * * For each Unicode code point from 0x10000 to 0x10FFFF: * - Call to_surrogate_pair, and make sure that: * - It returns true. * - uc is 0xD800..0xDBFF * - lc is 0xDC00..0xDFFF * - Call from_surrogate_pair on the pair, and make sure that * it returns the original character. * * For various invalid arguments to to_surrogate_pair * (U+0000..U+FFFF and U+110000...): * - Call to_surrogate_pair, and make sure it: * - Returns false. * - Sets *uc and *lc to REPLACEMENT_CHARACTER. * * For various invalid arguments to from_surrogate_pair * (uc: not 0xD800..0xDBFF, lc: not 0xDC00..0xDFFF): * - Call from_surrogate_pair, and make sure * it returns REPLACEMENT_CHARACTER. */ #define INVALID_TRIAL_COUNT 10000 #define range(r, lo, hi) ((r) % ((hi)-(lo)+1) + (lo)) static void test_valid(void) { uchar_t unicode; unsigned int uc, lc; for (unicode = 0x10000; unicode <= 0x10FFFF; unicode++) { if (to_surrogate_pair(unicode, &uc, &lc) != true) { fail("to_surrogate_pair did not return true on valid input."); return; } if (!(uc >= 0xD800 && uc <= 0xDBFF)) { fail("to_surrogate_pair: uc is out of range"); return; } if (!(lc >= 0xDC00 && lc <= 0xDFFF)) { fail("to_surrogate_pair: lc is out of range"); return; } if (from_surrogate_pair(uc, lc) != unicode) { fail("Surrogate pair conversion did not preserve original value (U+%04lX).", (unsigned long)unicode); return; } } pass("to_surrogate_pair and from_surrogate_pair work for all valid arguments."); } static void test_invalid_to_surrogate_pair(void) { long i; uchar_t unicode; unsigned int uc, lc; for (i = 1; i <= INVALID_TRIAL_COUNT; i++) { if (rand32() % 2) { unicode = range(rand32(), 0x0, 0xFFFF); } else { do { unicode = rand32(); } while (unicode < 0x110000); } if (to_surrogate_pair(unicode, &uc, &lc) != false) { fail("to_surrogate_pair did not return false on invalid input."); return; } if (uc != REPLACEMENT_CHARACTER || lc != REPLACEMENT_CHARACTER) { fail("to_surrogate_pair did not set uc and lc to the replacement character on invalid input."); return; } } pass("to_surrogate_pair seems to handle invalid argument values properly."); } static void test_invalid_from_surrogate_pair(void) { long i; unsigned int uc, lc; for (i = 1; i <= INVALID_TRIAL_COUNT; i++) { switch (rand32() % 3) { case 0: uc = range(rand32(), 0x0, 0xD7FF); break; case 1: uc = range(rand32(), 0xDC00, 0xDFFF); break; default: uc = range(rand32(), 0xE000, 0xFFFF); break; } switch (rand32() % 3) { case 0: lc = range(rand32(), 0x0, 0xD7FF); break; case 1: lc = range(rand32(), 0xD800, 0xDBFF); break; default: lc = range(rand32(), 0xE000, 0xFFFF); break; } if (from_surrogate_pair(uc, lc) != REPLACEMENT_CHARACTER) { fail("from_surrogate_pair(0x%04X, 0x%04X) did not return the replacement character", uc, lc); return; } } pass("from_surrogate_pair seems to handle invalid arguments properly."); } int main(void) { plan_tests(3); test_valid(); test_invalid_to_surrogate_pair(); test_invalid_from_surrogate_pair(); return exit_status(); }