1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * COPYRIGHT:
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Copyright (c) 1998-2006, International Business Machines Corporation and
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ********************************************************************/
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File test.c
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date          Name        Description
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   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
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LENGTHOF(array) (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);
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestFwdBack(void);
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestSetChar(void);
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppendChar(void);
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppend(void);
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestSurrogates(void);
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid addUTF8Test(TestNode** root);
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruaddUTF8Test(TestNode** root)
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestCodeUnitValues,    "utf8tst/TestCodeUnitValues");
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestCharLength,        "utf8tst/TestCharLength"    );
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestGetChar,           "utf8tst/TestGetChar"       );
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestNextPrevChar,      "utf8tst/TestNextPrevChar"  );
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestFwdBack,           "utf8tst/TestFwdBack"       );
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestSetChar,           "utf8tst/TestSetChar"       );
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestAppendChar,        "utf8tst/TestAppendChar"    );
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestAppend,            "utf8tst/TestAppend"        );
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  addTest(root, &TestSurrogates,        "utf8tst/TestSurrogates"    );
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCodeUnitValues()
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t codeunit[]={0x00, 0x65, 0x7e, 0x7f, 0xc0, 0xc4, 0xf0, 0xfd, 0x80, 0x81, 0xbc, 0xbe,};
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i;
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(codeunit)/sizeof(codeunit[0]); i++){
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uint8_t c=codeunit[i];
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_verbose("Testing code unit value of %x\n", c);
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(i<4){
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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)){
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a single byte but results in single: %c lead: %c trail: %c\n",
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if(i< 8){
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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)){
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a lead byte but results in single: %c lead: %c trail: %c\n",
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if(i< 12){
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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)){
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: 0x%02x is a trail 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        }
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestCharLength()
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint32_t codepoint[]={
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1, 0x0061,
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1, 0x007f,
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2, 0x016f,
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2, 0x07ff,
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0x0865,
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0x20ac,
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x20402,
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x23456,
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x24506,
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x20402,
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4, 0x10402,
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0xd7ff,
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3, 0xe000,
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool multiple;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(codepoint)/sizeof(codepoint[0]); i=(int16_t)(i+2)){
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 c=codepoint[i+1];
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(UTF8_CHAR_LENGTH(c) != (uint16_t)codepoint[i] || U8_LENGTH(c) != (uint16_t)codepoint[i]){
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              log_err("The no: of code units for %lx:- Expected: %d Got: %d\n", c, codepoint[i], UTF8_CHAR_LENGTH(c));
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }else{
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              log_verbose("The no: of code units for %lx is %d\n",c, UTF8_CHAR_LENGTH(c) );
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        multiple=(UBool)(codepoint[i] == 1 ? FALSE : TRUE);
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(UTF8_NEED_MULTIPLE_UCHAR(c) != multiple){
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              log_err("ERROR: UTF8_NEED_MULTIPLE_UCHAR failed for %lx\n", c);
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestGetChar()
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]={
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  code unit,*/
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x7f,
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xe4,
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xba,
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x8c,
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xF0,
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc0,
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x65,
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x31,
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x9a,
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc9
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 result[]={
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     /*codepoint-unsafe,  codepoint-safe(not strict)  codepoint-safe(strict)*/
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,             0x61,                       0x61,
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x7f,             0x7f,                       0x7f,
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c,
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c ,
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x4e8c,           0x4e8c,                     0x4e8c,
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401 ,
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,          0x10401,                    0x10401,
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x25,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x65,             0x65,                       0x65,
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x31,             0x31,                       0x31,
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x31,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x240,            UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t i=0;
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 c;
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset=0;
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=0; offset<sizeof(input); offset++) {
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (offset < sizeof(input) - 1) {
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_GET_CHAR_UNSAFE(input, offset, c);
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(c != result[i]){
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_GET_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            U8_GET_UNSAFE(input, offset, c);
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(c != result[i]){
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: U8_GET_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_GET(input, 0, offset, sizeof(input), c);
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(UTF_IS_ERROR(result[i+1]) ? c >= 0 : c != result[i+1]){
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: UTF8_GET_CHAR_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c);
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, FALSE);
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(c != result[i+1]){
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: UTF8_GET_CHAR_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c);
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, TRUE);
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(c != result[i+2]){
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: UTF8_GET_CHAR_SAFE(strict) failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i=(uint16_t)(i+3);
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestNextPrevChar(){
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]={0x61, 0xf0, 0x90, 0x90, 0x81, 0xc0, 0x80, 0xfd, 0xbe, 0xc2, 0x61, 0x81, 0x90, 0x90, 0xf0, 0x00};
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 result[]={
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*next_unsafe    next_safe_ns        next_safe_s          prev_unsafe   prev_safe_ns         prev_safe_s*/
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0061,        0x0061,             0x0061,              0x0000,       0x0000,             0x0000,
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x10401,       0x10401,            0x10401,             0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841410,    UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xa1050,      UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841,       UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x00,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x61,         0x61,               0x61,
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x80,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xc2,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xfd,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x77e,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xbe,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xfd,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xa1,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x00,         UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,          0x61,               0x61,                0xc0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x10401,      0x10401,            0x10401,
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF_ERROR_VALUE,    UTF_ERROR_VALUE,
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0840,        UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x0000,        0x0000,             0x0000,              0x0061,       0x0061,             0x0061
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int32_t movedOffset[]={
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru   /*next_unsafe    next_safe_ns  next_safe_s       prev_unsafe   prev_safe_ns     prev_safe_s*/
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,            1,           1,                15,           15,               15,
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,            5,           5,                14,           14 ,              14,
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,            3,           3,                9,            13,               13,
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        4,            4,           4,                9,            12,               12,
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,            5,           5,                9,            11,               11,
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,            7,           7,                10,           10,               10,
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,            7,           7,                9,            9,                9,
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        8,            9,           9,                7,            7,                7,
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        9,            9,           9,                7,            7,                7,
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        11,           10,          10,               5,            5,                5,
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        11,           11,          11,               5,            5,                5,
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        12,           12,          12,               1,            1,                1,
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        13,           13,          13,               1,            1,                1,
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        14,           14,          14,               1,            1,                1,
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        14,           15,          15,               1,            1,                1,
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        14,           16,          16,               0,            0,                0,
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 c=0x0000;
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset=0;
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t setOffset=0;
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=0; offset<sizeof(input); offset++){
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if (offset < sizeof(input) - 2) { /* Can't have it go off the end of the array based on input */
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             setOffset=offset;
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             UTF8_NEXT_CHAR_UNSAFE(input, setOffset, c);
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(setOffset != movedOffset[i]){
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: UTF8_NEXT_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     offset, movedOffset[i], setOffset);
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(c != result[i]){
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: UTF8_NEXT_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             setOffset=offset;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             U8_NEXT_UNSAFE(input, setOffset, c);
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(setOffset != movedOffset[i]){
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: U8_NEXT_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     offset, movedOffset[i], setOffset);
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(c != result[i]){
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: U8_NEXT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, FALSE);
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+1], setOffset);
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+1]){
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c);
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_NEXT(input, setOffset, sizeof(input), c);
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_NEXT failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+1], setOffset);
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(UTF_IS_ERROR(result[i+1]) ? c >= 0 : c != result[i+1]){
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_NEXT failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c);
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, TRUE);
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+1]){
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+2], setOffset);
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+2]){
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i=i+6;
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=sizeof(input); offset > 0; --offset){
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_PREV_CHAR_UNSAFE(input, setOffset, c);
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+3]){
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+3], setOffset);
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+3]){
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+3], c);
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_PREV_CHAR_SAFE(input, 0, setOffset, c, FALSE);
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+4]){
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+4], setOffset);
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+4]){
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+4], c);
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_PREV(input, 0, setOffset, c);
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+4]){
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_PREV failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+4], setOffset);
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(UTF_IS_ERROR(result[i+4]) ? c >= 0 : c != result[i+4]){
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_PREV failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+4], c);
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_PREV_CHAR_SAFE(input, 0,  setOffset, c, TRUE);
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != movedOffset[i+5]){
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 offset, movedOffset[i+5], setOffset);
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(c != result[i+5]){
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+5], c);
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i=i+6;
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* test non-characters */
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        static const uint8_t nonChars[]={
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            0xef, 0xb7, 0x90,       /* U+fdd0 */
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            0xef, 0xbf, 0xbf,       /* U+feff */
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            0xf0, 0x9f, 0xbf, 0xbe, /* U+1fffe */
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            0xf0, 0xbf, 0xbf, 0xbf, /* U+3ffff */
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            0xf4, 0x8f, 0xbf, 0xbe  /* U+10fffe */
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        };
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 ch;
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t idx;
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for(idx=0; idx<(int32_t)sizeof(nonChars);) {
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            U8_NEXT(nonChars, idx, sizeof(nonChars), ch);
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(!U_IS_UNICODE_NONCHAR(ch)) {
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("U8_NEXT(before %d) failed to read a non-character\n", idx);
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for(idx=(int32_t)sizeof(nonChars); idx>0;) {
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            U8_PREV(nonChars, 0, idx, ch);
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(!U_IS_UNICODE_NONCHAR(ch)) {
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("U8_PREV(at %d) failed to read a non-character\n", idx);
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestFwdBack(){
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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};
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t fwd_unsafe[] ={1, 5, 6, 7,  9, 10, 11, 13, 14, 15, 16,  20, };
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t fwd_safe[]   ={1, 5, 6, 7, 9, 10, 11,  12, 13, 14, 15, 16, 17, 18};
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t back_unsafe[]={17, 16, 12, 11, 9, 7, 6, 5, 1, 0};
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t back_safe[]  ={17, 16, 15, 14, 13, 12, 11, 10, 9, 7, 6, 5, 1, 0};
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t Nvalue[]= {0, 1, 2, 3, 1, 2, 1, 5};
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t fwd_N_unsafe[] ={0, 1, 6, 10, 11, 14, 15};
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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 */
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t back_N_unsafe[]={18, 17, 12, 7, 6, 1, 0};
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t back_N_safe[]  ={18, 17, 15, 12, 11, 9, 7, 0};
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offunsafe=0, offsafe=0;
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offunsafe < sizeof(input)){
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_1_UNSAFE(input, offunsafe);
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != fwd_unsafe[i]){
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_unsafe offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe);
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offunsafe < sizeof(input)){
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_1_UNSAFE(input, offunsafe);
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != fwd_unsafe[i]){
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_1_UNSAFE offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe);
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe < sizeof(input)){
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_1_SAFE(input, offsafe, sizeof(input));
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_safe[i]){
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_safe offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe < sizeof(input)){
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_1(input, offsafe, sizeof(input));
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_safe[i]){
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_1 offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=sizeof(input);
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offunsafe > 0){
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_1_UNSAFE(input, offunsafe);
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != back_unsafe[i]){
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Backward_unsafe offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe);
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=sizeof(input);
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offunsafe > 0){
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_1_UNSAFE(input, offunsafe);
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != back_unsafe[i]){
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_BACK_1_UNSAFE offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe);
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe > 0){
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_1_SAFE(input, 0,  offsafe);
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_safe[i]){
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Backward_safe offset expected:%d, Got:%d\n", back_unsafe[i], offsafe);
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i=0;
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(offsafe > 0){
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_1(input, 0,  offsafe);
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_safe[i]){
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_BACK_1 offset expected:%d, Got:%d\n", back_unsafe[i], offsafe);
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i++;
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=0;
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]);
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != fwd_N_unsafe[i]){
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_N_unsafe offset=%d expected:%d, Got:%d\n", i, fwd_N_unsafe[i], offunsafe);
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=0;
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]);
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != fwd_N_unsafe[i]){
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_N_UNSAFE offset=%d expected:%d, Got:%d\n", i, fwd_N_unsafe[i], offunsafe);
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=0;
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_FWD_N_SAFE(input, offsafe, sizeof(input), Nvalue[i]);
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_N_safe[i]){
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: Forward_N_safe offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=0;
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_FWD_N(input, offsafe, sizeof(input), Nvalue[i]);
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != fwd_N_safe[i]){
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_FWD_N offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=sizeof(input);
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]);
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != back_N_unsafe[i]){
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: backward_N_unsafe offset=%d expected:%d, Got:%d\n", i, back_N_unsafe[i], offunsafe);
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offunsafe=sizeof(input);
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]);
539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offunsafe != back_N_unsafe[i]){
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_BACK_N_UNSAFE offset=%d expected:%d, Got:%d\n", i, back_N_unsafe[i], offunsafe);
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF8_BACK_N_SAFE(input, 0, offsafe, Nvalue[i]);
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_N_safe[i]){
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: backward_N_safe offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsafe=sizeof(input);
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_BACK_N(input, 0, offsafe, Nvalue[i]);
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(offsafe != back_N_safe[i]){
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("ERROR: U8_BACK_N offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestSetChar(){
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t input[]
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0xfe, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x00 };
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t start_unsafe[]
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    9,    9,    12,   13 };
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t start_safe[]
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13 };
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t limit_unsafe[]
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0,    1,    4,    4,    4,    5,    6,    7,    9,    9,    10,   10,   10,   15 };
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t limit_safe[]
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        = {0,    1,    4,    4,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13 };
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t i=0;
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offset=0, setOffset=0;
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(offset=0; offset<(int32_t)sizeof(input); offset++){
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_SET_CHAR_START_UNSAFE(input, setOffset);
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != start_unsafe[i]){
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_SET_CP_START_UNSAFE(input, setOffset);
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != start_unsafe[i]){
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_SET_CP_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_SET_CHAR_START_SAFE(input, 0, setOffset);
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != start_safe[i]){
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_SET_CHAR_START_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_SET_CP_START(input, 0, setOffset);
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != start_safe[i]){
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_SET_CP_START failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if (offset != 0) { /* Can't have it go off the end of the array */
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             setOffset=offset;
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             UTF8_SET_CHAR_LIMIT_UNSAFE(input, setOffset);
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(setOffset != limit_unsafe[i]){
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: UTF8_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             setOffset=offset;
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             U8_SET_CP_LIMIT_UNSAFE(input, setOffset);
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             if(setOffset != limit_unsafe[i]){
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 log_err("ERROR: U8_SET_CP_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             }
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         UTF8_SET_CHAR_LIMIT_SAFE(input,0, setOffset, sizeof(input));
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != limit_safe[i]){
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: UTF8_SET_CHAR_LIMIT_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         setOffset=offset;
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         U8_SET_CP_LIMIT(input,0, setOffset, sizeof(input));
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         if(setOffset != limit_safe[i]){
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru             log_err("ERROR: U8_SET_CP_LIMIT failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         }
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         i++;
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppendChar(){
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t s[11]={0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00};
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint32_t test[]={
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     /*append-position(unsafe),  CHAR to be appended  */
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,                        0x10401,
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2,                        0x0028,
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2,                        0x007f,
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0xd801,
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,                        0x20402,
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        8,                        0x10401,
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc0,
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc1,
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xfd,
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x80,
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x81,
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0xbf,
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,                        0xfe,
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*append-position(safe),     CHAR to be appended */
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,                        0x10401,
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        2,                        0x0028,
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0x7f,
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        3,                        0xd801,   /* illegal for UTF-8 starting with Unicode 3.2 */
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        1,                        0x20402,
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        9,                        0x10401,
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc0,
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xc1,
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        5,                        0xfd,
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x80,
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0x81,
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        6,                        0xbf,
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        7,                        0xfe,
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint16_t movedOffset[]={
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*offset-moved-to(unsafe)*/
666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,              /*for append-pos: 0 , CHAR 0x10401*/
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          3,
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          3,
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          6,
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          5,
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          12,
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          9,
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          /*offset-moved-to(safe)*/
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,              /*for append-pos: 0, CHAR  0x10401*/
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          3,
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          4,
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          6,
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          5,
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          11,
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          7,
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          8,
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          9,
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t result[][11]={
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*unsafe*/
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x7f, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0xed, 0xa0, 0x81, 0x67, 0x68, 0x69, 0x6a, 0x00},
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0xF0, 0x90, 0x90},
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*safe*/
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x7f, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0xef, 0xbf, 0xbf, 0x67, 0x68, 0x69, 0x6a, 0x00},
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xc2, 0x9f}, /*gets UTF8_ERROR_VALUE_2 which takes 2 bytes 0xc0, 0x9f*/
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t i, count=0;
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t str[12];
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t offset;
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*    UChar32 c=0;*/
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t size=sizeof(s)/sizeof(s[0]);
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<sizeof(test)/sizeof(test[0]); i=(uint16_t)(i+2)){
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memcpy(str, s, size);
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offset=test[i];
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(count<13){
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_APPEND_CHAR_UNSAFE(str, offset, test[i+1]);
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed for count=%d. \nExpected:", count);
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\nGot:      ");
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\n");
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }else{
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF8_APPEND_CHAR_SAFE(str, offset, size, test[i+1]);
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed for count=%d. \nExpected:", count);
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\nGot:     ");
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("\n");
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /*call the API instead of MACRO
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uprv_memcpy(str, s, size);
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            offset=test[i];
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c=test[i+1];
774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if((uint32_t)(c)<=0x7f) {
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  (str)[(offset)++]=(uint8_t)(c);
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 (offset)=utf8_appendCharSafeBody(str, (int32_t)(offset), (int32_t)(size), c);
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offset != movedOffset[count]){
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: utf8_appendCharSafeBody() failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count, movedOffset[count], offset);
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(uprv_memcmp(str, result[count], size) !=0){
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                log_err("ERROR: utf8_appendCharSafeBody() failed for count=%d. \nExpected:", count);
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(result[count], size);
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printf("\nGot:     ");
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printUChars(str, size);
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                printf("\n");
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            */
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count++;
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void TestAppend() {
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 codePoints[]={
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61, 0xdf, 0x901, 0x3040,
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xac00, 0xd800, 0xdbff, 0xdcde,
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xdffd, 0xe000, 0xffff, 0x10000,
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x12345, 0xe0021, 0x10ffff, 0x110000,
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x234567, 0x7fffffff, -1, -1000,
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0, 0x400
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t expectUnsafe[]={
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xea, 0xb0, 0x80,  0xed, 0xa0, 0x80,  0xed, 0xaf, 0xbf,  0xed, 0xb3, 0x9e,
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xbf, 0xbd,  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* none from this line */
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,  0xd0, 0x80
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }, expectSafe[]={
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xea, 0xb0, 0x80,  /* no surrogates */
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no surrogates */  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* none from this line */
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0,  0xd0, 0x80
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t buffer[100];
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 c;
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i, length;
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool isError, expectIsError, wrongIsError;
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=0;
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<LENGTHOF(codePoints); ++i) {
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        c=codePoints[i];
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(c<0 || 0x10ffff<c) {
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            continue; /* skip non-code points for U8_APPEND_UNSAFE */
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_APPEND_UNSAFE(buffer, length, c);
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(length!=LENGTHOF(expectUnsafe) || 0!=memcmp(buffer, expectUnsafe, length)) {
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND_UNSAFE did not generate the expected output\n");
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=0;
843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    wrongIsError=FALSE;
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<LENGTHOF(codePoints); ++i) {
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        c=codePoints[i];
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        expectIsError= c<0 || 0x10ffff<c || U_IS_SURROGATE(c);
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        isError=FALSE;
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_APPEND(buffer, length, LENGTHOF(buffer), c, isError);
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        wrongIsError|= isError!=expectIsError;
851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(wrongIsError) {
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND did not set isError correctly\n");
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(length!=LENGTHOF(expectSafe) || 0!=memcmp(buffer, expectSafe, length)) {
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("U8_APPEND did not generate the expected output\n");
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruTestSurrogates() {
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const uint8_t b[]={
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xc3, 0x9f,             /*  00DF */
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0x9f, 0xbf,       /*  D7FF */
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xa0, 0x81,       /*  D801 */
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xed, 0xbf, 0xbe,       /*  DFFE */
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xee, 0x80, 0x80,       /*  E000 */
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xf0, 0x97, 0xbf, 0xbe  /* 17FFE */
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar32 cp[]={
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        0xdf, 0xd7ff, 0xd801, 0xdffe, 0xe000, 0x17ffe
872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 cu, cs, cl;
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i, j, k, iu, is, il, length;
876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    k=0; /* index into cp[] */
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length=LENGTHOF(b);
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<length;) {
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_NEXT_UNSAFE(b, j, cu);
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iu=j;
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_NEXT(b, j, length, cs);
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        is=j;
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        L8_NEXT(b, j, length, cl);
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        il=j;
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cu!=cp[k]) {
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* U8_NEXT() returns <0 for surrogate code points */
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* L8_NEXT() returns surrogate code points like U8_NEXT_UNSAFE() */
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cl!=cu) {
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("L8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(is!=iu || il!=iu) {
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_NEXT(b[%ld]) or L8_NEXT(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++k;    /* next code point */
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i=iu;   /* advance by one UTF-8 sequence */
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(i>0) {
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        --k; /* previous code point */
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_PREV_UNSAFE(b, j, cu);
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iu=j;
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        U8_PREV(b, 0, j, cs);
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        is=j;
924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        j=i;
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        L8_PREV(b, 0, j, cl);
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        il=j;
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cu!=cp[k]) {
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* U8_PREV() returns <0 for surrogate code points */
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* L8_PREV() returns surrogate code points like U8_PREV_UNSAFE() */
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(cl!=cu) {
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("L8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(is!=iu || il !=iu) {
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_err("U8_PREV(b[%ld]) or L8_PREV(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i=iu;   /* go back by one UTF-8 sequence */
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void printUChars(const uint8_t *uchars, int16_t len){
952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int16_t i=0;
953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(i=0; i<len; i++){
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("0x%02x ", *(uchars+i));
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
957