1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************
254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * COPYRIGHT:
354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Copyright (c) 1998-2012, International Business Machines Corporation and
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ********************************************************************/
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius* File utf8tst.c
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date          Name        Description
1254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius*   07/24/2000    Madhu       Creation
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utf8.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cintltst.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* lenient UTF-8 ------------------------------------------------------------ */
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Lenient UTF-8 differs from conformant UTF-8 in that it allows surrogate
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * code points with their "natural" encoding.
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Effectively, this allows a mix of UTF-8 and CESU-8 as well as encodings of
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * single surrogates.
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is not conformant with UTF-8.
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Supplementary code points may be encoded as pairs of 3-byte sequences, but
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the macros below do not attempt to assemble such pairs.
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define L8_NEXT(s, i, length, c) { \
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    (c)=(uint8_t)(s)[(i)++]; \
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if((c)>=0x80) { \
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U8_IS_LEAD(c)) { \
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (int32_t)(length), c, -2); \
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else { \
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (c)=U_SENTINEL; \
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } \
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } \
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define L8_PREV(s, start, i, c) { \
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    (c)=(uint8_t)(s)[--(i)]; \
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if((c)>=0x80) { \
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if((c)<=0xbf) { \
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -2); \
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else { \
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (c)=U_SENTINEL; \
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } \
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } \
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* -------------------------------------------------------------------------- */
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void printUChars(const uint8_t *uchars, int16_t len);
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCodeUnitValues(void);
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCharLength(void);
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestGetChar(void);
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestNextPrevChar(void);
678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic void TestNulTerminated(void);
6854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestNextPrevNonCharacters(void);
6954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestNextPrevCharUnsafe(void);
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestFwdBack(void);
7154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestFwdBackUnsafe(void);
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestSetChar(void);
7354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestSetCharUnsafe(void);
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppendChar(void);
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppend(void);
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestSurrogates(void);
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid addUTF8Test(TestNode** root);
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruaddUTF8Test(TestNode** root)
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
8354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestCodeUnitValues,          "utf8tst/TestCodeUnitValues");
8454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestCharLength,              "utf8tst/TestCharLength");
8554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestGetChar,                 "utf8tst/TestGetChar");
8654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestNextPrevChar,            "utf8tst/TestNextPrevChar");
878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    addTest(root, &TestNulTerminated,           "utf8tst/TestNulTerminated");
8854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestNextPrevNonCharacters,   "utf8tst/TestNextPrevNonCharacters");
8954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestNextPrevCharUnsafe,      "utf8tst/TestNextPrevCharUnsafe");
9054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestFwdBack,                 "utf8tst/TestFwdBack");
9154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestFwdBackUnsafe,           "utf8tst/TestFwdBackUnsafe");
9254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestSetChar,                 "utf8tst/TestSetChar");
9354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestSetCharUnsafe,           "utf8tst/TestSetCharUnsafe");
9454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestAppendChar,              "utf8tst/TestAppendChar");
9554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestAppend,                  "utf8tst/TestAppend");
9654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    addTest(root, &TestSurrogates,              "utf8tst/TestSurrogates");
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCodeUnitValues()
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t codeunit[]={0x00, 0x65, 0x7e, 0x7f, 0xc0, 0xc4, 0xf0, 0xfd, 0x80, 0x81, 0xbc, 0xbe,};
10254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i;
10454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(codeunit); i++){
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uint8_t c=codeunit[i];
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_verbose("Testing code unit value of %x\n", c);
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(i<4){
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(!UTF8_IS_SINGLE(c) || UTF8_IS_LEAD(c) || UTF8_IS_TRAIL(c) || !U8_IS_SINGLE(c) || U8_IS_LEAD(c) || U8_IS_TRAIL(c)){
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a single byte but results in single: %c lead: %c trail: %c\n",
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if(i< 8){
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(!UTF8_IS_LEAD(c) || UTF8_IS_SINGLE(c) || UTF8_IS_TRAIL(c) || !U8_IS_LEAD(c) || U8_IS_SINGLE(c) || U8_IS_TRAIL(c)){
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a lead byte but results in single: %c lead: %c trail: %c\n",
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if(i< 12){
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(!UTF8_IS_TRAIL(c) || UTF8_IS_SINGLE(c) || UTF8_IS_LEAD(c) || !U8_IS_TRAIL(c) || U8_IS_SINGLE(c) || U8_IS_LEAD(c)){
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a trail byte but results in single: %c lead: %c trail: %c\n",
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCharLength()
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint32_t codepoint[]={
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1, 0x0061,
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1, 0x007f,
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2, 0x016f,
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2, 0x07ff,
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0x0865,
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0x20ac,
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x20402,
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x23456,
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x24506,
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x20402,
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x10402,
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0xd7ff,
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0xe000,
14254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
14454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i;
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool multiple;
14754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(codepoint); i=(int16_t)(i+2)){
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 c=codepoint[i+1];
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(UTF8_CHAR_LENGTH(c) != (uint16_t)codepoint[i] || U8_LENGTH(c) != (uint16_t)codepoint[i]){
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              log_err("The no: of code units for %lx:- Expected: %d Got: %d\n", c, codepoint[i], UTF8_CHAR_LENGTH(c));
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }else{
15254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius              log_verbose("The no: of code units for %lx is %d\n",c, UTF8_CHAR_LENGTH(c));
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        multiple=(UBool)(codepoint[i] == 1 ? FALSE : TRUE);
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(UTF8_NEED_MULTIPLE_UCHAR(c) != multiple){
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              log_err("ERROR: UTF8_NEED_MULTIPLE_UCHAR failed for %lx\n", c);
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestGetChar()
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]={
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  code unit,*/
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x7f,
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xe4,
16854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xba,
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x8c,
17054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xF0,
17154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x90,
17254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x90,
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc0,
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x65,
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x31,
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x9a,
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc9
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 result[]={
18154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*  codepoint-unsafe, codepoint-safe(not strict)  codepoint-safe(strict) */
18254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x61,             0x61,                       0x61,
18354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x7f,             0x7f,                       0x7f,
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c,
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c ,
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c,
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401,
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x25,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
19254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x65,             0x65,                       0x65,
19354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x31,             0x31,                       0x31,
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x31,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x240,            UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t i=0;
1988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UChar32 c, expected;
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset=0;
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=0; offset<sizeof(input); offset++) {
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (offset < sizeof(input) - 1) {
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_GET_CHAR_UNSAFE(input, offset, c);
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(c != result[i]){
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_GET_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
20654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            U8_GET_UNSAFE(input, offset, c);
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(c != result[i]){
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: U8_GET_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
21254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, FALSE);
2178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        expected=result[i+1];
2188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
2198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: UTF8_GET_CHAR_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
2218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_GET(input, 0, offset, sizeof(input), c);
2238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
2248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
2258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_GET failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_GET_OR_FFFD(input, 0, offset, sizeof(input), c);
2298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(expected<0) { expected=0xfffd; }
2308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
2318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_GET_OR_FFFD failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, TRUE);
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(c != result[i+2]){
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: UTF8_GET_CHAR_SAFE(strict) failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
23854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        i=(uint16_t)(i+3);
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
24354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestNextPrevChar() {
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]={0x61, 0xf0, 0x90, 0x90, 0x81, 0xc0, 0x80, 0xfd, 0xbe, 0xc2, 0x61, 0x81, 0x90, 0x90, 0xf0, 0x00};
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 result[]={
24654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*  next_unsafe    next_safe_ns        next_safe_s          prev_unsafe   prev_safe_ns        prev_safe_s */
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0061,        0x0061,             0x0061,              0x0000,       0x0000,             0x0000,
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,       0x10401,            0x10401,             0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841410,    UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xa1050,      UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841,       UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x00,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x61,         0x61,               0x61,
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x80,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xc2,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xfd,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x77e,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xbe,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xfd,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xa1,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x00,         UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,          0x61,               0x61,                0xc0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x10401,      0x10401,            0x10401,
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF_ERROR_VALUE,    UTF_ERROR_VALUE,
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0840,        UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0000,        0x0000,             0x0000,              0x0061,       0x0061,             0x0061
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int32_t movedOffset[]={
26554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*  next_unsafe   next_safe_ns next_safe_s       prev_unsafe   prev_safe_ns      prev_safe_s */
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,            1,           1,                15,           15,               15,
26754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        5,            5,           5,                14,           14 ,              14,
26854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        3,            3,           3,                9,            13,               13,
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4,            4,           4,                9,            12,               12,
27054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        5,            5,           5,                9,            11,               11,
27154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        7,            7,           7,                10,           10,               10,
27254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        7,            7,           7,                9,            9,                9,
27354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        8,            9,           9,                7,            7,                7,
27454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        9,            9,           9,                7,            7,                7,
27554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        11,           10,          10,               5,            5,                5,
27654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        11,           11,          11,               5,            5,                5,
27754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        12,           12,          12,               1,            1,                1,
27854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        13,           13,          13,               1,            1,                1,
27954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        14,           14,          14,               1,            1,                1,
28054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        14,           15,          15,               1,            1,                1,
28154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        14,           16,          16,               0,            0,                0,
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
28354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* TODO: remove unused columns for next_unsafe & prev_unsafe, and adjust the test code */
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UChar32 c, expected;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset=0;
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t setOffset=0;
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=0; offset<sizeof(input); offset++){
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, FALSE);
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+1], setOffset);
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
2968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        expected=result[i+1];
2978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
2988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_NEXT(input, setOffset, sizeof(input), c);
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_NEXT failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+1], setOffset);
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
3078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
3088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
3098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_NEXT failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
3118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
3128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        setOffset=offset;
3138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_NEXT_OR_FFFD(input, setOffset, sizeof(input), c);
3148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(setOffset != movedOffset[i+1]){
3158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_NEXT_OR_FFFD failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                offset, movedOffset[i+1], setOffset);
3178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
3188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(expected<0) { expected=0xfffd; }
3198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
3208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_NEXT_OR_FFFD failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, TRUE);
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+2], setOffset);
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+2]){
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i=i+6;
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=sizeof(input); offset > 0; --offset){
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_PREV_CHAR_SAFE(input, 0, setOffset, c, FALSE);
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+4]){
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+4], setOffset);
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
3448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        expected=result[i+4];
3458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
3468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: UTF8_PREV_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_PREV(input, 0, setOffset, c);
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+4]){
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_PREV failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+4], setOffset);
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
3558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
3568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
3578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_PREV failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
3598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
3608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        setOffset=offset;
3618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_PREV_OR_FFFD(input, 0, setOffset, c);
3628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(setOffset != movedOffset[i+4]){
3638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_PREV_OR_FFFD failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                offset, movedOffset[i+4], setOffset);
3658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
3668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(expected<0) { expected=0xfffd; }
3678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c != expected){
3688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("ERROR: U8_PREV_OR_FFFD failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_PREV_CHAR_SAFE(input, 0,  setOffset, c, TRUE);
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+5]){
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+5], setOffset);
37654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         }
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+5]){
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+5], c);
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i=i+6;
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
38354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* keep this in sync with utf16tst.c's TestNulTerminated() */
3868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic void TestNulTerminated() {
3878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    static const uint8_t input[]={
3888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*  0 */  0x61,
3898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*  1 */  0xf0, 0x90, 0x90, 0x81,
3908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*  5 */  0xc0, 0x80,
3918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*  7 */  0xdf, 0x80,
3928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*  9 */  0xc2,
3938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 10 */  0x62,
3948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 11 */  0xfd, 0xbe,
3958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 13 */  0xe0, 0xa0, 0x80,
3968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 16 */  0xe2, 0x82, 0xac,
3978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 19 */  0xf0, 0x90, 0x90,
3988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 22 */  0x00
3998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /* 23 */
4008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    };
4018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    static const UChar32 result[]={
4028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x61,
4038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x10401,
4048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U_SENTINEL,
4058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x7c0,
4068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U_SENTINEL,
4078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x62,
4088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U_SENTINEL,
4098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x800,
4108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0x20ac,
4118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U_SENTINEL,
4128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        0
4138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    };
4148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
4158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UChar32 c, c2, expected;
4168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t i0, i=0, j, k, expectedIndex;
4178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t cpIndex=0;
4188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    do {
4198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        i0=i;
4208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_NEXT(input, i, -1, c);
4218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        expected=result[cpIndex];
4228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c!=expected) {
4238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("U8_NEXT(from %d)=U+%04x != U+%04x\n", i0, c, expected);
4248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
4258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        j=i0;
4268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_NEXT_OR_FFFD(input, j, -1, c);
4278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(expected<0) { expected=0xfffd; }
4288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(c!=expected) {
4298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("U8_NEXT_OR_FFFD(from %d)=U+%04x != U+%04x\n", i0, c, expected);
4308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
4318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(j!=i) {
4328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("U8_NEXT_OR_FFFD() moved to index %d but U8_NEXT() moved to %d\n", j, i);
4338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
4348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        j=i0;
4358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_FWD_1(input, j, -1);
4368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(j!=i) {
4378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("U8_FWD_1() moved to index %d but U8_NEXT() moved to %d\n", j, i);
4388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
4398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        ++cpIndex;
4408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        /*
4418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius         * Move by this many code points from the start.
4428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius         * U8_FWD_N() stops at the end of the string, that is, at the NUL if necessary.
4438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius         */
4448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        expectedIndex= (c==0) ? i-1 : i;
4458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        k=0;
4468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_FWD_N(input, k, -1, cpIndex);
4478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if(k!=expectedIndex) {
4488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            log_err("U8_FWD_N(code points from 0) moved to index %d but expected %d\n", k, expectedIndex);
4498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
4508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    } while(c!=0);
4518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
4528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    i=0;
4538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    do {
4548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        j=i0=i;
4558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        U8_NEXT(input, i, -1, c);
4568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        do {
4578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            U8_GET(input, 0, j, -1, c2);
4588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if(c2!=c) {
4598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                log_err("U8_NEXT(from %d)=U+%04x != U+%04x=U8_GET(at %d)\n", i0, c, c2, j);
4608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
4618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            U8_GET_OR_FFFD(input, 0, j, -1, c2);
4628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            expected= (c>=0) ? c : 0xfffd;
4638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if(c2!=expected) {
4648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                log_err("U8_NEXT_OR_FFFD(from %d)=U+%04x != U+%04x=U8_GET_OR_FFFD(at %d)\n", i0, expected, c2, j);
4658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
4668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            /* U8_SET_CP_LIMIT moves from a non-lead byte to the limit of the code point */
4678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            k=j+1;
4688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            U8_SET_CP_LIMIT(input, 0, k, -1);
4698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if(k!=i) {
4708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                log_err("U8_NEXT() moved to %d but U8_SET_CP_LIMIT(%d) moved to %d\n", i, j+1, k);
4718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
4728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } while(++j<i);
4738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    } while(c!=0);
4748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
4758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
47654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestNextPrevNonCharacters() {
47754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* test non-characters */
47854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const uint8_t nonChars[]={
47954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xef, 0xb7, 0x90,       /* U+fdd0 */
48054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xef, 0xbf, 0xbf,       /* U+feff */
48154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf0, 0x9f, 0xbf, 0xbe, /* U+1fffe */
48254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf0, 0xbf, 0xbf, 0xbf, /* U+3ffff */
48354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf4, 0x8f, 0xbf, 0xbe  /* U+10fffe */
48454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    };
48554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
48654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar32 ch;
48754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t idx;
48854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
48954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(idx=0; idx<(int32_t)sizeof(nonChars);) {
49054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_NEXT(nonChars, idx, sizeof(nonChars), ch);
49154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(!U_IS_UNICODE_NONCHAR(ch)) {
49254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("U8_NEXT(before %d) failed to read a non-character\n", idx);
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
49454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
49554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(idx=(int32_t)sizeof(nonChars); idx>0;) {
49654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_PREV(nonChars, 0, idx, ch);
49754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(!U_IS_UNICODE_NONCHAR(ch)) {
49854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("U8_PREV(at %d) failed to read a non-character\n", idx);
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
50354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestNextPrevCharUnsafe() {
50454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*
50554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * Use a (mostly) well-formed UTF-8 string and test at code point boundaries.
50654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * The behavior of _UNSAFE macros for ill-formed strings is undefined.
50754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     */
50854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const uint8_t input[]={
50954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x61,
51054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf0, 0x90, 0x90, 0x81,
51154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xc0, 0x80,  /* non-shortest form */
51254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xe2, 0x82, 0xac,
51354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xc2, 0xa1,
51454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf4, 0x8f, 0xbf, 0xbf,
51554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x00
51654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    };
51754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const UChar32 codePoints[]={
51854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x61,
51954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x10401,
52054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0,
52154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x20ac,
52254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xa1,
52354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x10ffff,
52454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0
52554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    };
52654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
52754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar32 c;
52854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i;
52954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    uint32_t offset;
53054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0, offset=0; offset<sizeof(input); ++i) {
53154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_NEXT_CHAR_UNSAFE(input, offset, c);
53254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(c != codePoints[i]){
53354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_NEXT_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
53454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    offset, codePoints[i], c);
53554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
53654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
53754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0, offset=0; offset<sizeof(input); ++i) {
53854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_NEXT_UNSAFE(input, offset, c);
53954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(c != codePoints[i]){
54054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_NEXT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
54154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    offset, codePoints[i], c);
54254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
54354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
54454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
54554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=LENGTHOF(codePoints)-1, offset=sizeof(input); offset > 0; --i){
54654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         UTF8_PREV_CHAR_UNSAFE(input, offset, c);
54754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         if(c != codePoints[i]){
54854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius             log_err("ERROR: UTF8_PREV_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
54954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     offset, codePoints[i], c);
55054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         }
55154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
55254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=LENGTHOF(codePoints)-1, offset=sizeof(input); offset > 0; --i){
55354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         U8_PREV_UNSAFE(input, offset, c);
55454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         if(c != codePoints[i]){
55554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius             log_err("ERROR: U8_PREV_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
55654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     offset, codePoints[i], c);
55754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         }
55854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
55954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
56054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
56154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestFwdBack() {
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]={0x61, 0xF0, 0x90, 0x90, 0x81, 0xff, 0x62, 0xc0, 0x80, 0x7f, 0x8f, 0xc0, 0x63, 0x81, 0x90, 0x90, 0xF0, 0x00};
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t fwd_safe[]   ={1, 5, 6, 7, 9, 10, 11,  12, 13, 14, 15, 16, 17, 18};
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t back_safe[]  ={17, 16, 15, 14, 13, 12, 11, 10, 9, 7, 6, 5, 1, 0};
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t Nvalue[]= {0, 1, 2, 3, 1, 2, 1, 5};
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t fwd_N_safe[]   ={0, 1, 6, 10, 11, 13, 14, 18}; /*safe macro keeps it at the end of the string */
56854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const uint16_t back_N_safe[]  ={18, 17, 15, 12, 11, 9, 7, 0};
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    uint32_t offsafe=0;
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe < sizeof(input)){
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_1_SAFE(input, offsafe, sizeof(input));
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_safe[i]){
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_safe offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe < sizeof(input)){
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_1(input, offsafe, sizeof(input));
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_safe[i]){
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_1 offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe > 0){
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_1_SAFE(input, 0,  offsafe);
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_safe[i]){
59554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: Backward_safe offset expected:%d, Got:%d\n", back_safe[i], offsafe);
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe > 0){
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_1(input, 0,  offsafe);
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_safe[i]){
60554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_BACK_1 offset expected:%d, Got:%d\n", back_safe[i], offsafe);
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=0;
61154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(Nvalue); i++){
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_N_SAFE(input, offsafe, sizeof(input), Nvalue[i]);
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_N_safe[i]){
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_N_safe offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
61654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=0;
62054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(Nvalue); i++){
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_N(input, offsafe, sizeof(input), Nvalue[i]);
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_N_safe[i]){
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_N offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
62954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(Nvalue); i++){
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_N_SAFE(input, 0, offsafe, Nvalue[i]);
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_N_safe[i]){
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: backward_N_safe offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
63754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(Nvalue); i++){
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_N(input, 0, offsafe, Nvalue[i]);
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_N_safe[i]){
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_BACK_N offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
64554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestFwdBackUnsafe() {
64654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*
64754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * Use a (mostly) well-formed UTF-8 string and test at code point boundaries.
64854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * The behavior of _UNSAFE macros for ill-formed strings is undefined.
64954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     */
65054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const uint8_t input[]={
65154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x61,
65254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf0, 0x90, 0x90, 0x81,
65354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xc0, 0x80,  /* non-shortest form */
65454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xe2, 0x82, 0xac,
65554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xc2, 0xa1,
65654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0xf4, 0x8f, 0xbf, 0xbf,
65754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        0x00
65854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    };
65954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const int8_t boundaries[]={ 0, 1, 5, 7, 10, 12, 16, 17 };
66054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
66154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t offset;
66254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i;
66354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=1, offset=0; offset<LENGTHOF(input); ++i) {
66454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_FWD_1_UNSAFE(input, offset);
66554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]){
66654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_FWD_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
66754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
66854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
66954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=1, offset=0; offset<LENGTHOF(input); ++i) {
67054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_FWD_1_UNSAFE(input, offset);
67154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]){
67254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_FWD_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
67354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
67454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
67554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
67654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=LENGTHOF(boundaries)-2, offset=LENGTHOF(input); offset>0; --i) {
67754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_BACK_1_UNSAFE(input, offset);
67854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]){
67954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_BACK_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
68054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
68154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
68254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=LENGTHOF(boundaries)-2, offset=LENGTHOF(input); offset>0; --i) {
68354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_BACK_1_UNSAFE(input, offset);
68454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]){
68554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_BACK_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
68654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
68754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
68854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
68954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(boundaries); ++i) {
69054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        offset=0;
69154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_FWD_N_UNSAFE(input, offset, i);
69254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]) {
69354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_FWD_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
69454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
69554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
69654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(boundaries); ++i) {
69754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        offset=0;
69854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_FWD_N_UNSAFE(input, offset, i);
69954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[i]) {
70054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_FWD_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
70154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
70254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
70354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
70454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(boundaries); ++i) {
70554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        int32_t j=LENGTHOF(boundaries)-1-i;
70654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        offset=LENGTHOF(input);
70754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_BACK_N_UNSAFE(input, offset, i);
70854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[j]) {
70954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_BACK_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[j], offset);
71054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
71154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
71254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(boundaries); ++i) {
71354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        int32_t j=LENGTHOF(boundaries)-1-i;
71454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        offset=LENGTHOF(input);
71554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_BACK_N_UNSAFE(input, offset, i);
71654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(offset != boundaries[j]) {
71754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_BACK_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[j], offset);
71854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
71954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
72054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
72154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
72254dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestSetChar() {
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0xfe, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x00 };
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t start_safe[]
72654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,  14 };
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t limit_safe[]
72854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        = {0,    1,    4,    4,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,  14 };
72954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offset=0, setOffset=0;
73254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(offset=0; offset<=LENGTHOF(input); offset++){
73354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (offset<LENGTHOF(input)){
73454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
73554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            UTF8_SET_CHAR_START_SAFE(input, 0, setOffset);
73654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != start_safe[i]){
73754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: UTF8_SET_CHAR_START_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
73854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
74154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            U8_SET_CP_START(input, 0, setOffset);
74254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != start_safe[i]){
74354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: U8_SET_CP_START failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
74454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
74554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        setOffset=offset;
74854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UTF8_SET_CHAR_LIMIT_SAFE(input,0, setOffset, sizeof(input));
74954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(setOffset != limit_safe[i]){
75054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: UTF8_SET_CHAR_LIMIT_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
75154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
75354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        setOffset=offset;
75454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        U8_SET_CP_LIMIT(input,0, setOffset, sizeof(input));
75554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(setOffset != limit_safe[i]){
75654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            log_err("ERROR: U8_SET_CP_LIMIT failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
75754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
75954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        i++;
76054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
76154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
76354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void TestSetCharUnsafe() {
76454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const uint8_t input[]
76554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0x2e, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x80, 0x80, 0x00 };
76654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const int16_t start_unsafe[]
76754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    9,    9,    12,   12,   12,   15 };
76854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    static const int16_t limit_unsafe[]
76954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        = {0,    1,    4,    4,    4,    5,    6,    7,    9,    9,    10,   10,   10,   15,   15,   15,   16 };
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
77154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    uint32_t i=0;
77254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t offset=0, setOffset=0;
77354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(offset=0; offset<=LENGTHOF(input); offset++){
77454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (offset<LENGTHOF(input)){
77554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
77654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            UTF8_SET_CHAR_START_UNSAFE(input, setOffset);
77754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != start_unsafe[i]){
77854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: UTF8_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
77954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
78054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
78154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
78254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            U8_SET_CP_START_UNSAFE(input, setOffset);
78354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != start_unsafe[i]){
78454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: U8_SET_CP_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
78554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
78654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
78754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
78854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (offset != 0) { /* Can't have it go off the end of the array */
78954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
79054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            UTF8_SET_CHAR_LIMIT_UNSAFE(input, setOffset);
79154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != limit_unsafe[i]){
79254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: UTF8_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
79354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
79454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
79554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            setOffset=offset;
79654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            U8_SET_CP_LIMIT_UNSAFE(input, setOffset);
79754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(setOffset != limit_unsafe[i]){
79854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: U8_SET_CP_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
79954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
80054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
80254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        i++;
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppendChar(){
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t s[11]={0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00};
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint32_t test[]={
80954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*  append-position(unsafe),  CHAR to be appended */
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,                        0x10401,
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2,                        0x0028,
81254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        2,                        0x007f,
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0xd801,
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,                        0x20402,
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        8,                        0x10401,
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc0,
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc1,
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xfd,
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x80,
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x81,
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0xbf,
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,                        0xfe,
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*  append-position(safe),    CHAR to be appended */
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,                        0x10401,
82654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        2,                        0x0028,
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0x7f,
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0xd801,   /* illegal for UTF-8 starting with Unicode 3.2 */
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,                        0x20402,
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        9,                        0x10401,
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc0,
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc1,
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xfd,
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x80,
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x81,
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0xbf,
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,                        0xfe,
83854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t movedOffset[]={
84154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* offset-moved-to(unsafe) */
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,              /*for append-pos: 0 , CHAR 0x10401*/
84354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          3,
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          3,
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          6,
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          5,
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          12,
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
84954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          7,
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          9,
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
85654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* offset-moved-to(safe) */
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,              /*for append-pos: 0, CHAR  0x10401*/
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          3,
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          6,
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          5,
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          11,
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
86454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          7,
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          9,
87054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
87254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t result[][11]={
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*unsafe*/
87554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
87654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
87754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0x62, 0x7f, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
87854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0x62, 0x63, 0xed, 0xa0, 0x81, 0x67, 0x68, 0x69, 0x6a, 0x00},
87954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0xF0, 0x90, 0x90},
88154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
88554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*safe*/
89254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
89354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x7f, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
89554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0x62, 0x63, 0xef, 0xbf, 0xbf, 0x67, 0x68, 0x69, 0x6a, 0x00},
89654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xc2, 0x9f}, /*gets UTF8_ERROR_VALUE_2 which takes 2 bytes 0xc0, 0x9f*/
89854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
90254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
90654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
90854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t i, count=0;
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t str[12];
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset;
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*    UChar32 c=0;*/
91454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    uint16_t size=LENGTHOF(s);
91554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for(i=0; i<LENGTHOF(test); i=(uint16_t)(i+2)){
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memcpy(str, s, size);
91754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        offset=test[i];
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(count<13){
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_APPEND_CHAR_UNSAFE(str, offset, test[i+1]);
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
92154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
92354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed for count=%d. \nExpected:", count);
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\nGot:      ");
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\n");
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }else{
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_APPEND_CHAR_SAFE(str, offset, size, test[i+1]);
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
93554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
93754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed for count=%d. \nExpected:", count);
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\nGot:     ");
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\n");
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /*call the API instead of MACRO
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uprv_memcpy(str, s, size);
94854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            offset=test[i];
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c=test[i+1];
95054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if((uint32_t)(c)<=0x7f) {
95154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                  (str)[(offset)++]=(uint8_t)(c);
95254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            } else {
95354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                 (offset)=utf8_appendCharSafeBody(str, (int32_t)(offset), (int32_t)(size), c);
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
95654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                log_err("ERROR: utf8_appendCharSafeBody() failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
95854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: utf8_appendCharSafeBody() failed for count=%d. \nExpected:", count);
962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printf("\nGot:     ");
964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printf("\n");
966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            */
968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count++;
97054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
97154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppend() {
976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 codePoints[]={
977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61, 0xdf, 0x901, 0x3040,
978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xac00, 0xd800, 0xdbff, 0xdcde,
979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xdffd, 0xe000, 0xffff, 0x10000,
980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x12345, 0xe0021, 0x10ffff, 0x110000,
981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x234567, 0x7fffffff, -1, -1000,
982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0, 0x400
983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t expectUnsafe[]={
985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xea, 0xb0, 0x80,  0xed, 0xa0, 0x80,  0xed, 0xaf, 0xbf,  0xed, 0xb3, 0x9e,
987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xbf, 0xbd,  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* none from this line */
990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,  0xd0, 0x80
991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }, expectSafe[]={
992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xea, 0xb0, 0x80,  /* no surrogates */
994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no surrogates */  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* none from this line */
997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,  0xd0, 0x80
998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t buffer[100];
1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 c;
1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i, length;
1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool isError, expectIsError, wrongIsError;
1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=0;
1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<LENGTHOF(codePoints); ++i) {
1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        c=codePoints[i];
1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(c<0 || 0x10ffff<c) {
1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            continue; /* skip non-code points for U8_APPEND_UNSAFE */
1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_APPEND_UNSAFE(buffer, length, c);
1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(length!=LENGTHOF(expectUnsafe) || 0!=memcmp(buffer, expectUnsafe, length)) {
1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND_UNSAFE did not generate the expected output\n");
1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=0;
1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    wrongIsError=FALSE;
1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<LENGTHOF(codePoints); ++i) {
1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        c=codePoints[i];
1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        expectIsError= c<0 || 0x10ffff<c || U_IS_SURROGATE(c);
1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        isError=FALSE;
1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_APPEND(buffer, length, LENGTHOF(buffer), c, isError);
1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        wrongIsError|= isError!=expectIsError;
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(wrongIsError) {
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND did not set isError correctly\n");
1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(length!=LENGTHOF(expectSafe) || 0!=memcmp(buffer, expectSafe, length)) {
1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND did not generate the expected output\n");
1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruTestSurrogates() {
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t b[]={
1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc3, 0x9f,             /*  00DF */
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0x9f, 0xbf,       /*  D7FF */
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xa0, 0x81,       /*  D801 */
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xbf, 0xbe,       /*  DFFE */
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xee, 0x80, 0x80,       /*  E000 */
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x97, 0xbf, 0xbe  /* 17FFE */
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 cp[]={
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xdf, 0xd7ff, 0xd801, 0xdffe, 0xe000, 0x17ffe
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 cu, cs, cl;
1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i, j, k, iu, is, il, length;
1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    k=0; /* index into cp[] */
1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=LENGTHOF(b);
1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<length;) {
1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_NEXT_UNSAFE(b, j, cu);
1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iu=j;
1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_NEXT(b, j, length, cs);
1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        is=j;
1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        L8_NEXT(b, j, length, cl);
1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        il=j;
1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cu!=cp[k]) {
1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* U8_NEXT() returns <0 for surrogate code points */
1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* L8_NEXT() returns surrogate code points like U8_NEXT_UNSAFE() */
1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cl!=cu) {
1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("L8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(is!=iu || il!=iu) {
1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT(b[%ld]) or L8_NEXT(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++k;    /* next code point */
1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i=iu;   /* advance by one UTF-8 sequence */
1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(i>0) {
1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        --k; /* previous code point */
1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_PREV_UNSAFE(b, j, cu);
1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iu=j;
1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_PREV(b, 0, j, cs);
1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        is=j;
1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        L8_PREV(b, 0, j, cl);
1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        il=j;
1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cu!=cp[k]) {
1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* U8_PREV() returns <0 for surrogate code points */
1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* L8_PREV() returns surrogate code points like U8_PREV_UNSAFE() */
1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cl!=cu) {
1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("L8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(is!=iu || il !=iu) {
1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV(b[%ld]) or L8_PREV(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i=iu;   /* go back by one UTF-8 sequence */
1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void printUChars(const uint8_t *uchars, int16_t len){
1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i=0;
1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<len; i++){
1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("0x%02x ", *(uchars+i));
1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1133