diff --git a/common/core/desktop/src/kmx/kmx_xstring.cpp b/common/core/desktop/src/kmx/kmx_xstring.cpp index 384582919c..54fc87c1d2 100644 --- a/common/core/desktop/src/kmx/kmx_xstring.cpp +++ b/common/core/desktop/src/kmx/kmx_xstring.cpp @@ -178,13 +178,11 @@ PKMX_WCHAR km::kbp::kmx::decxstr(PKMX_WCHAR p, PKMX_WCHAR pStart) return p-1; } - if (*(p - 1) == UC_SENTINEL) { - // TODO: validate that *p <= CODE_LASTCODE? What do we do if it isn't? - return p - 1; - } - - q = p - 2; - for (int i = 2; i < CODE__SIZE_MAX && q >= pStart; i++, q--) { + // Look for a UC_SENTINEL to jump to + // note: If we are pointing to the middle of a UC_SENTINEL CODE_x, then we won't treat it as valid, + // and will just go back a single wchar + q = p; + for (int i = 0; i < CODE__SIZE_MAX && q >= pStart; i++, q--) { // *q == UC_SENTINEL && *(q + 1) is within CODE__SIZE && next CODE_ right of UC_SENTINEL ( looked up in CODE__SIZE+1) has value i if (*q == UC_SENTINEL && *(q + 1) <= CODE_LASTCODE && CODE__SIZE[*(q + 1)] + 1 == i) return q; diff --git a/common/core/desktop/tests/unit/kmnkbd/test_kmx_xstring.cpp b/common/core/desktop/tests/unit/kmnkbd/test_kmx_xstring.cpp index c33c8c24ae..5d49053f7f 100644 --- a/common/core/desktop/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/common/core/desktop/tests/unit/kmnkbd/test_kmx_xstring.cpp @@ -11,13 +11,14 @@ #include #include #include "../../../src/kmx/kmx_xstring.h" +#include "../../../src/kmx/kmx_file.h" #include "../test_assert.h" using namespace km::kbp::kmx; using namespace std; PKMX_WCHAR find_ptr_to_last_character(PKMX_WCHAR p_first) { - int length = wcslen((const wchar_t *)p_first); + int length = std::u16string(p_first).length(); if (length > 0) return p_first + length - 1; else @@ -26,11 +27,60 @@ PKMX_WCHAR find_ptr_to_last_character(PKMX_WCHAR p_first) { void test_decxstr() { - - PKMX_WCHAR p_start; // pointer start of input + + PKMX_WCHAR p_start; // pointer start of input PKMX_WCHAR p; // pointer end of input PKMX_WCHAR q; // pointer output + // ------------------------------------------------------------------------------------------------------------------------------------------------------- + // even more tests: check for use with non-CODE__SIZE + // ------------------------------------------------------------------------------------------------------------------------------------------------------- + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p-1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0001"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0002"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0001\u0001"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0002\u0001"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0001\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0002\u0001\u0001"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\uF000\u0002\u0001\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); + // ------------------------------------------------------------------------------------------------------------------------------------------------------- // more tests: check if we might end up left of pstart // ------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -55,10 +105,12 @@ void test_decxstr() { q = decxstr(p, p_start); assert(q == (p - 1)); + // Note: this test puts the pointer into the middle of a valid `UC_SENTINEL CODE_ANY ` + // so we should expect it to not be properly understood. p_start = (PKMX_WCHAR)u"\uFFFF\u0001\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 2)); + assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\uFFFF\u0001\u0001\u0001"; p = find_ptr_to_last_character(p_start); @@ -100,10 +152,12 @@ void test_decxstr() { q = decxstr(p, p_start); assert(q == (p - 1)); + // 0x14 = CODE_IFOPT which has 3 parameters, so this is an invalid, so + // go back only one char p_start = (PKMX_WCHAR)u"\uFFFF\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-2 )); + assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\uFFFF\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); @@ -127,77 +181,77 @@ void test_decxstr() { // ------------------------------------------------------------------------------------------------------------------------------------------------------- // -- differences in pointer movement for new decxstr ---------------------------------------------------------------------------------------------------- - // ----- OLD version of decxstr: 0x0A not used => return ( p - 1) , 0x0C not used => return ( p - 1) , 0x0E = 1 => return ( p - 3) - // ----- NEW version of decxstr: Values set in in CODE__SIZE[]: 0x0A = 2 => return ( p - 4) , 0x0C =1 => return ( p - 3) , 0x0E = 0 => return ( p - 1) - // ------------------------------------------------------------------------------------------------------------------------------------------------------- + // ----- OLD version of decxstr: 0x0A not used => return ( p - 1) , 0x0C not used => return ( p - 1) , 0x0E = 1 => return ( p - 3) + // ----- NEW version of decxstr: Values set in in CODE__SIZE[]: 0x0A = 2 => return ( p - 4) , 0x0C =1 => return ( p - 3) , 0x0E = 0 => return ( p - 1) + // ------------------------------------------------------------------------------------------------------------------------------------------------------- - // runs OK with NEW version of decxstr (with CODE_EXTENDED pointer moves 3 ( 4 altogether) - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 4) ); - - //runs OK with NEW version of decxstr (with CODE_SWITCH pointer moves 2 ( 3 altogether) - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000C\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 3) ); - - // runs OK with NEW version of decxstr (with CODE_CLEARCONTEXT pointer moves 0 ( 1 altogether) - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000E\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - // runs OK with OLD version and NEW version of decxstr - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000E\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - // --------------------------------------------------------------------------------------- - // ---- character - // --------------------------------------------------------------------------------------- - - p_start = (PKMX_WCHAR)u"abcd"; + // runs OK with NEW version of decxstr (with CODE_EXTENDED pointer moves 3 ( 4 altogether) + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - + assert(q == (p - 4) ); + + //runs OK with NEW version of decxstr (with CODE_SWITCH pointer moves 2 ( 3 altogether) + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000C\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 3) ); + + // runs OK with NEW version of decxstr (with CODE_CLEARCONTEXT pointer moves 0 ( 1 altogether) + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000E\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1) ); + + // runs OK with OLD version and NEW version of decxstr + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000E\u0001"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 2) ); + + // --------------------------------------------------------------------------------------- + // ---- character + // --------------------------------------------------------------------------------------- + + p_start = (PKMX_WCHAR)u"abcd"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1) ); // --------------------------------------------------------------------------------------- // ---- p <= pstart // --------------------------------------------------------------------------------------- - + p_start = (PKMX_WCHAR)u"abc"; - p = find_ptr_to_last_character(p_start)-5; + p = find_ptr_to_last_character(p_start)-5; q = decxstr(p, p_start); assert(q == (NULL) ); - p_start = (PKMX_WCHAR)u"a"; + p_start = (PKMX_WCHAR)u"a"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); assert(q == (NULL) ); - + // --------------------------------------------------------------------------------------- // ---- p= UC_SENTINEL_EXTENDED // --------------------------------------------------------------------------------------- - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0002\u0003\u0004\u0010"; + + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0002\u0003\u0004\u0010"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0010"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0002\u0003\u0004\u0005\u0010d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); assert(q == (p - 8) ); - + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0010d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); @@ -206,388 +260,176 @@ void test_decxstr() { // --------------------------------------------------------------------------------------- // ---- Surrogate Pair // --------------------------------------------------------------------------------------- - - p_start = (PKMX_WCHAR)u"abc\U0001F609"; + + p_start = (PKMX_WCHAR)u"abc\U0001F609"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - p = find_ptr_to_last_character(p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\U0001F609d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + assert(q == (p - 1) ); + + p_start = (PKMX_WCHAR)u"abc\U0001F609d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); assert(q == (p - 2) ); - + // --------------------------------------------------------------------------------------- - // ---- CODE_ + // ---- CODE_ // --------------------------------------------------------------------------------------- - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); +#define C_UC_SENTINEL u"\uFFFF" - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); + for (auto code = 1 /* CODE_ANY */; code <= CODE_LASTCODE; code++) { + if (code == UC_SENTINEL_EXTENDEDEND) { + // We won't try and test that here as it won't assert in the + // same way + continue; + } + auto size = CODE__SIZE[code]; + std::u16string str(u"abc" C_UC_SENTINEL); + str.append(1, code); + str.append(size < 0 ? 0 : size, u'\u0001'); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0003\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); + p_start = (PKMX_WCHAR) str.c_str(); + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0004\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0005\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0006\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0007\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0008\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000A\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000C\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000E\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000F\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0011\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0012\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0013\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0015\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0017\u0001\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0016\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0018\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); + str.append(u"a"); + p_start = (PKMX_WCHAR)str.c_str(); + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + if (size < 0) { + assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit + } else { + assert(q == (p - size - 2)); /* UC_SENTINEL + code + (CODE__SIZE = number of params) */ + } + } // --------------------------------------------------------------------------------------- // ---- CODE_ followed by letter // --------------------------------------------------------------------------------------- - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 4) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0003\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0003\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0004\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0004\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0005\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0005\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0006\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0006\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0007\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0007\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0008\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0008\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 3) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u000F\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 3) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0011\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0012\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u000F\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0013\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0011\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); + assert(q == (p - 3) ); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0012\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 3) ); + + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0013\u0001\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); assert(q == (p - 4) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 5) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0015\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 3) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0016\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 3) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0017\u0001\u0001\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 5) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0018\u0001\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 4) ); - - // --------------------------------------------------------------------------------------- - // ---- malformed CODE_ too short & too long - // --------------------------------------------------------------------------------------- - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0005d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0015\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1 )); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0001\u0001d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0016\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 4) ); + q = decxstr(p, p_start); + assert(q == (p - 3) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0014\u0001\u0001\u0001d"; + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0017\u0001\u0001\u0001d"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 5) ); + p_start = (PKMX_WCHAR)u"abc\uFFFF\u0018\u0001\u0001d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 4) ); + // --------------------------------------------------------------------------------------- - // ---- \0 in sequence + // ---- other // --------------------------------------------------------------------------------------- - - p_start = (PKMX_WCHAR)u"abc\0"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"abc\0d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"\0\U0001F609"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\uFFFF\0\u0014\u0014\u0014d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\uFFFF\u0014\0\u0014\u0014d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == p - 1 ); - - p_start = (PKMX_WCHAR)u"\uFFFF\u0014\u0014\0\u0014d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == p - 2 ); - - p_start = (PKMX_WCHAR)u"\uFFFF\u0014\u0014\u0014\0d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == p - 1 ); - - p_start = (PKMX_WCHAR)u"\0"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"d\0"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\0d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\uFFFF\0"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\0\uFFFF"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == NULL ); - - p_start = (PKMX_WCHAR)u"\U0001F609\0"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - // --------------------------------------------------------------------------------------- - // ---- other - // --------------------------------------------------------------------------------------- - p_start = (PKMX_WCHAR)u"abc\uFFFF\u0002def\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"abc\uFFFF"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); - assert(q == (p - 1) ); - - p_start = (PKMX_WCHAR)u"\uFFFF\U0001F609"; + p_start = (PKMX_WCHAR)u"abc\uFFFF"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 2) ); - - p_start = (PKMX_WCHAR)u"\u0014d"; - p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"\uFFFF"; + // pointer in the middle of a surrogate pair, so beware! + p_start = (PKMX_WCHAR)u"\uFFFF\U0001F609"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1) ); + + p_start = (PKMX_WCHAR)u"\u0014d"; + p = find_ptr_to_last_character(p_start); + q = decxstr(p, p_start); + assert(q == (p - 1) ); + + p_start = (PKMX_WCHAR)u"\uFFFF"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); assert(q == NULL ); - p_start = (PKMX_WCHAR)u"\uFFFFd"; + p_start = (PKMX_WCHAR)u"\uFFFFd"; p = find_ptr_to_last_character(p_start); - q = decxstr(p, p_start); + q = decxstr(p, p_start); assert(q == (p - 1) ); - p_start = (PKMX_WCHAR)u"\uFFFF\uFFFF"; + p_start = (PKMX_WCHAR)u"\uFFFF\uFFFF"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); assert(q == p - 1 ); @@ -648,7 +490,7 @@ void test_decxstr() { q = incxstr(p); assert(q == p + 3); - // --- Test for FFFF CODE_EXTENDED -------------------------------------------------------------------------------------------------------- + // --- Test for FFFF CODE_EXTENDED -------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\uFFFF\u000A\u0001\u0002\u0003\u0004\u0005\u0006\u0010"; q = incxstr(p); assert(q == p + 9); @@ -736,7 +578,7 @@ void test_decxstr() { // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITH \0 AT DIFFERENT POSITIONS -------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------------------------------- - + // --- Test for FFFF + control (earlier p+1) with \0 after first position --------------- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR)u"\uFFFF\0\u0008\u0001"; q = incxstr(p); @@ -756,18 +598,18 @@ void test_decxstr() { p = (PKMX_WCHAR)u"\uFFFF\u0002\u0001\u0001\0"; q = incxstr(p); assert(q == p+4); - + // --- Test for FFFF +control (earlier p+3) with \0 after fifth position ----- unit test failed with old version of incxstr() --------- p = (PKMX_WCHAR)u"\uFFFF\u0014\u0001\u0001\u0001\0"; q = incxstr(p); assert(q == p+5); - - // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 6. position ----- unit test failed with old version of incxstr() ----- + + // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 6. position ----- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR)u"\uFFFF\u000A\u0001\u0002\u0003\u0004\0\u0005\u0006\u0007\u0010"; q = incxstr(p); assert(q == p + 6); - // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 7. position ----- unit test failed with old version of incxstr() + // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 7. position ----- unit test failed with old version of incxstr() p = (PKMX_WCHAR)u"\uFFFF\u000A\u0001\u0002\u0003\u0004\u0005\0\u0006\u0007\u0010"; q = incxstr(p); assert(q == p + 7);