xref: /aosp_15_r20/external/unicode/harness.c (revision c14be686ac162d87fd361a4e7a5439b56849c4f4)
1*c14be686SAndroid Build Coastguard Worker /*
2*c14be686SAndroid Build Coastguard Worker  * Copyright 2001-2004 Unicode, Inc.
3*c14be686SAndroid Build Coastguard Worker  *
4*c14be686SAndroid Build Coastguard Worker  * Disclaimer
5*c14be686SAndroid Build Coastguard Worker  *
6*c14be686SAndroid Build Coastguard Worker  * This source code is provided as is by Unicode, Inc. No claims are
7*c14be686SAndroid Build Coastguard Worker  * made as to fitness for any particular purpose. No warranties of any
8*c14be686SAndroid Build Coastguard Worker  * kind are expressed or implied. The recipient agrees to determine
9*c14be686SAndroid Build Coastguard Worker  * applicability of information provided. If this file has been
10*c14be686SAndroid Build Coastguard Worker  * purchased on magnetic or optical media from Unicode, Inc., the
11*c14be686SAndroid Build Coastguard Worker  * sole remedy for any claim will be exchange of defective media
12*c14be686SAndroid Build Coastguard Worker  * within 90 days of receipt.
13*c14be686SAndroid Build Coastguard Worker  *
14*c14be686SAndroid Build Coastguard Worker  * Limitations on Rights to Redistribute This Code
15*c14be686SAndroid Build Coastguard Worker  *
16*c14be686SAndroid Build Coastguard Worker  * Unicode, Inc. hereby grants the right to freely use the information
17*c14be686SAndroid Build Coastguard Worker  * supplied in this file in the creation of products supporting the
18*c14be686SAndroid Build Coastguard Worker  * Unicode Standard, and to make copies of this file in any form
19*c14be686SAndroid Build Coastguard Worker  * for internal or external distribution as long as this notice
20*c14be686SAndroid Build Coastguard Worker  * remains attached.
21*c14be686SAndroid Build Coastguard Worker  *
22*c14be686SAndroid Build Coastguard Worker  * harness.c
23*c14be686SAndroid Build Coastguard Worker  *
24*c14be686SAndroid Build Coastguard Worker  * This is a test harness for "ConvertUTF.c".  Compile this
25*c14be686SAndroid Build Coastguard Worker  * and run without arguments.  It will exhaustively test
26*c14be686SAndroid Build Coastguard Worker  * the conversion routines, and print a few lines of diagnostic
27*c14be686SAndroid Build Coastguard Worker  * output.  You don't need to compile ConvertUTF.c itself,
28*c14be686SAndroid Build Coastguard Worker  * since it gets #included here along with the header.
29*c14be686SAndroid Build Coastguard Worker  * Example of a compile line:
30*c14be686SAndroid Build Coastguard Worker  *
31*c14be686SAndroid Build Coastguard Worker  *		$	gcc -g harness.c -o harness
32*c14be686SAndroid Build Coastguard Worker  *
33*c14be686SAndroid Build Coastguard Worker  * Rev History: Rick McGowan, new file April 2001.
34*c14be686SAndroid Build Coastguard Worker  * Sept 19, 2002: Corrected error on line 234:  utf16_buf[2] becomes utf16_result[2]
35*c14be686SAndroid Build Coastguard Worker  * 	per report from Iain Murray.
36*c14be686SAndroid Build Coastguard Worker  * July 3, 2003: Updated printout message.
37*c14be686SAndroid Build Coastguard Worker  * Oct 19, 2004: Updated isLegalUTF8 test data and corrected switch statements to catch
38*c14be686SAndroid Build Coastguard Worker  *	illegal surrogate use in UTF-8, per report from Frank Tang.
39*c14be686SAndroid Build Coastguard Worker  *
40*c14be686SAndroid Build Coastguard Worker  */
41*c14be686SAndroid Build Coastguard Worker 
42*c14be686SAndroid Build Coastguard Worker #define CVTUTF_DEBUG 1
43*c14be686SAndroid Build Coastguard Worker 
44*c14be686SAndroid Build Coastguard Worker #include <stdio.h>
45*c14be686SAndroid Build Coastguard Worker #include "ConvertUTF.c"
46*c14be686SAndroid Build Coastguard Worker 
47*c14be686SAndroid Build Coastguard Worker /* ---------------------------------------------------------------------
48*c14be686SAndroid Build Coastguard Worker 	test01 - Spot check a few legal & illegal UTF-8 values only.
49*c14be686SAndroid Build Coastguard Worker 	This is not an exhaustive test, just a brief one that was
50*c14be686SAndroid Build Coastguard Worker 	used to develop the "isLegalUTF8" routine.
51*c14be686SAndroid Build Coastguard Worker 
52*c14be686SAndroid Build Coastguard Worker 	Legal UTF-8 sequences are:
53*c14be686SAndroid Build Coastguard Worker 
54*c14be686SAndroid Build Coastguard Worker 	1st----	2nd----	3rd----	4th----	Codepoints---
55*c14be686SAndroid Build Coastguard Worker 
56*c14be686SAndroid Build Coastguard Worker 	00-7F				  0000-  007F
57*c14be686SAndroid Build Coastguard Worker 	C2-DF	80-BF			  0080-  07FF
58*c14be686SAndroid Build Coastguard Worker 	E0	A0-BF	80-BF		  0800-  0FFF
59*c14be686SAndroid Build Coastguard Worker 	E1-EC   80-BF   80-BF             1000-  CFFF
60*c14be686SAndroid Build Coastguard Worker 	ED      80-9F   80-BF             D000-  D7FF
61*c14be686SAndroid Build Coastguard Worker 	EE-EF   80-BF   80-BF             E000-  FFFF
62*c14be686SAndroid Build Coastguard Worker 	F0	90-BF	80-BF	80-BF	 10000- 3FFFF
63*c14be686SAndroid Build Coastguard Worker 	F1-F3	80-BF	80-BF	80-BF	 40000- FFFFF
64*c14be686SAndroid Build Coastguard Worker 	F4	80-8F	80-BF	80-BF	100000-10FFFF
65*c14be686SAndroid Build Coastguard Worker 
66*c14be686SAndroid Build Coastguard Worker    --------------------------------------------------------------------- */
67*c14be686SAndroid Build Coastguard Worker 
68*c14be686SAndroid Build Coastguard Worker 
69*c14be686SAndroid Build Coastguard Worker struct utf8_test {
70*c14be686SAndroid Build Coastguard Worker     Boolean utf8_legal;	/* is legal sequence? */
71*c14be686SAndroid Build Coastguard Worker     int utf8_len;	/* length of sequence */
72*c14be686SAndroid Build Coastguard Worker     unsigned char utf8_seq[5];	/* the sequence */
73*c14be686SAndroid Build Coastguard Worker };
74*c14be686SAndroid Build Coastguard Worker 
75*c14be686SAndroid Build Coastguard Worker struct utf8_test utf8_testData[] = {
76*c14be686SAndroid Build Coastguard Worker     { 1,	1,	{ 0x7A, 0x00, 0x00, 0x00, 0x00 }},	/* 0 */
77*c14be686SAndroid Build Coastguard Worker     { 1,	2,	{ 0xC2, 0xAC, 0x00, 0x00, 0x00 }},	/* 1 */
78*c14be686SAndroid Build Coastguard Worker     { 1,	2,	{ 0xDF, 0xB2, 0x00, 0x00, 0x00 }},	/* 2 */
79*c14be686SAndroid Build Coastguard Worker     { 1,	3,	{ 0xE0, 0xA1, 0x81, 0x00, 0x00 }},	/* 3 */
80*c14be686SAndroid Build Coastguard Worker     { 1,	3,	{ 0xE1, 0xAC, 0x90, 0x00, 0x00 }},	/* 4 */
81*c14be686SAndroid Build Coastguard Worker     { 1,	3,	{ 0xF0, 0x93, 0xB2, 0xA1, 0x00 }},	/* 5 */
82*c14be686SAndroid Build Coastguard Worker     { 1,	4,	{ 0xF1, 0x87, 0x9A, 0xB0, 0x00 }},	/* 6 */
83*c14be686SAndroid Build Coastguard Worker     { 1,	4,	{ 0xF3, 0x88, 0x9B, 0xAD, 0x00 }},	/* 7 */
84*c14be686SAndroid Build Coastguard Worker     { 1,	4,	{ 0xF4, 0x82, 0x89, 0x8F, 0x00 }},	/* 8 */
85*c14be686SAndroid Build Coastguard Worker 
86*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0x82, 0x00, 0x00, 0x00, 0x00 }},	/* 9 */
87*c14be686SAndroid Build Coastguard Worker     { 0,	2,	{ 0xF8, 0xAC, 0x00, 0x00, 0x00 }},	/* 10 */
88*c14be686SAndroid Build Coastguard Worker     { 0,	2,	{ 0xE1, 0xFC, 0xFF, 0x00, 0x00 }},	/* 11 */
89*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0xC2, 0xFC, 0x00, 0x00, 0x00 }},	/* 12 */
90*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0xE1, 0xC2, 0x81, 0x00, 0x00 }},	/* 13 */
91*c14be686SAndroid Build Coastguard Worker     { 0,	2,	{ 0xC2, 0xC1, 0x00, 0x00, 0x00 }},	/* 14 */
92*c14be686SAndroid Build Coastguard Worker     { 0,	2,	{ 0xC0, 0xAF, 0x00, 0x00, 0x00 }},	/* 15 */
93*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0xE0, 0x9F, 0x80, 0x00, 0x00 }},	/* 16 */
94*c14be686SAndroid Build Coastguard Worker     { 0,	4,	{ 0xF0, 0x93, 0xB2, 0xC1, 0x00 }},	/* 17 */
95*c14be686SAndroid Build Coastguard Worker 
96*c14be686SAndroid Build Coastguard Worker     { 1,	3,	{ 0xED, 0x9F, 0xBF, 0x00, 0x00 }},	/* 18 */
97*c14be686SAndroid Build Coastguard Worker     { 1,	3,	{ 0xEE, 0x80, 0x80, 0x00, 0x00 }},	/* 19 */
98*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0xED, 0xA0, 0x80, 0x00, 0x00 }},	/* 20 */
99*c14be686SAndroid Build Coastguard Worker     { 0,	3,	{ 0xED, 0xBF, 0xBF, 0x00, 0x00 }},	/* 21 */
100*c14be686SAndroid Build Coastguard Worker 
101*c14be686SAndroid Build Coastguard Worker /* for all > 21 use "short" buffer lengths to detect over-run */
102*c14be686SAndroid Build Coastguard Worker     { 0,	4,	{ 0xF0, 0x93, 0xB2, 0xC3, 0x00 }},	/* 18 use short buflen */
103*c14be686SAndroid Build Coastguard Worker     { 0,	0,	{ 0x00, 0x00, 0x00, 0x00, 0x00 }},
104*c14be686SAndroid Build Coastguard Worker 
105*c14be686SAndroid Build Coastguard Worker };
106*c14be686SAndroid Build Coastguard Worker 
test01()107*c14be686SAndroid Build Coastguard Worker int test01() {
108*c14be686SAndroid Build Coastguard Worker 	int i;
109*c14be686SAndroid Build Coastguard Worker 	int rval, wantVal1, wantVal2, gotVal1, gotVal2, len2;
110*c14be686SAndroid Build Coastguard Worker 
111*c14be686SAndroid Build Coastguard Worker 	printf("Begin Test01\n"); fflush(stdout);
112*c14be686SAndroid Build Coastguard Worker 
113*c14be686SAndroid Build Coastguard Worker 	rval = 0;
114*c14be686SAndroid Build Coastguard Worker 	for (i = 0; utf8_testData[i].utf8_len; i++) {
115*c14be686SAndroid Build Coastguard Worker 		wantVal1 = wantVal2 = utf8_testData[i].utf8_legal;
116*c14be686SAndroid Build Coastguard Worker 		gotVal1 = isLegalUTF8(&(utf8_testData[i].utf8_seq[0]), utf8_testData[i].utf8_len);
117*c14be686SAndroid Build Coastguard Worker 		/* use truncated length for tests over 21 */
118*c14be686SAndroid Build Coastguard Worker 		if (i <= 21) { len2 = 4; } else { len2 = utf8_testData[i].utf8_len-1; wantVal2 = 0; }
119*c14be686SAndroid Build Coastguard Worker 		gotVal2 = isLegalUTF8Sequence(&(utf8_testData[i].utf8_seq[0]), &(utf8_testData[i].utf8_seq[0])+len2);
120*c14be686SAndroid Build Coastguard Worker 		if ((gotVal1 != wantVal1) || (gotVal2 != wantVal2)) {
121*c14be686SAndroid Build Coastguard Worker 			printf("Test01 error: seq %d is %d & %d (should be %d & %d) for bytes (%x,%x,%x,%x,%x,) & len %d\n",
122*c14be686SAndroid Build Coastguard Worker 			i, gotVal1, gotVal2, wantVal1, wantVal2, utf8_testData[i].utf8_seq[0],
123*c14be686SAndroid Build Coastguard Worker 			utf8_testData[i].utf8_seq[1], utf8_testData[i].utf8_seq[2],
124*c14be686SAndroid Build Coastguard Worker 			utf8_testData[i].utf8_seq[3], utf8_testData[i].utf8_seq[4],
125*c14be686SAndroid Build Coastguard Worker 			utf8_testData[i].utf8_len);
126*c14be686SAndroid Build Coastguard Worker 			++rval;
127*c14be686SAndroid Build Coastguard Worker 		}
128*c14be686SAndroid Build Coastguard Worker 	}
129*c14be686SAndroid Build Coastguard Worker 
130*c14be686SAndroid Build Coastguard Worker 	return (rval ? 0 : 1);
131*c14be686SAndroid Build Coastguard Worker }
132*c14be686SAndroid Build Coastguard Worker 
133*c14be686SAndroid Build Coastguard Worker 
134*c14be686SAndroid Build Coastguard Worker /* ---------------------------------------------------------------------
135*c14be686SAndroid Build Coastguard Worker 	test02 - Test round trip UTF32 -> UTF16 -> UTF8 -> UTF16 -> UTF32
136*c14be686SAndroid Build Coastguard Worker 
137*c14be686SAndroid Build Coastguard Worker 	This is an exhaustive test of values 0 through 0x10FFFF.  It
138*c14be686SAndroid Build Coastguard Worker 	takes each integer value and converts from UTC4 through the
139*c14be686SAndroid Build Coastguard Worker 	other encoding forms, and back to UTR32, checking the results
140*c14be686SAndroid Build Coastguard Worker 	along the way.
141*c14be686SAndroid Build Coastguard Worker 
142*c14be686SAndroid Build Coastguard Worker 	It does not check the un-paired low surrogates, except for
143*c14be686SAndroid Build Coastguard Worker 	the first low surrogate.  It intends to get that one illegal
144*c14be686SAndroid Build Coastguard Worker 	result, prints a message, and continues with tests.
145*c14be686SAndroid Build Coastguard Worker 
146*c14be686SAndroid Build Coastguard Worker    --------------------------------------------------------------------- */
147*c14be686SAndroid Build Coastguard Worker 
test02()148*c14be686SAndroid Build Coastguard Worker int test02() {
149*c14be686SAndroid Build Coastguard Worker 	int i, n;
150*c14be686SAndroid Build Coastguard Worker 	ConversionResult result;
151*c14be686SAndroid Build Coastguard Worker 	UTF32 utf32_buf[2], utf32_result[2];
152*c14be686SAndroid Build Coastguard Worker 	UTF16 utf16_buf[3], utf16_result[3];
153*c14be686SAndroid Build Coastguard Worker 	UTF8 utf8_buf[8];
154*c14be686SAndroid Build Coastguard Worker 	UTF32 *utf32SourceStart, *utf32TargetStart;
155*c14be686SAndroid Build Coastguard Worker 	UTF16 *utf16SourceStart, *utf16TargetStart;
156*c14be686SAndroid Build Coastguard Worker 	UTF8 *utf8SourceStart, *utf8TargetStart;
157*c14be686SAndroid Build Coastguard Worker 
158*c14be686SAndroid Build Coastguard Worker 	printf("Begin Test02\n"); fflush(stdout);
159*c14be686SAndroid Build Coastguard Worker 
160*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i <= 0x10FFFF; i++) {
161*c14be686SAndroid Build Coastguard Worker 		utf32_buf[0] = i; utf32_buf[1] = 0;
162*c14be686SAndroid Build Coastguard Worker 		utf32_result[0] = utf32_result[1] = 0;
163*c14be686SAndroid Build Coastguard Worker 		utf16_buf[0] = utf16_buf[1] = utf16_buf[2] = 0;
164*c14be686SAndroid Build Coastguard Worker 		utf16_result[0] = utf16_result[1] = utf16_result[2] = 0;
165*c14be686SAndroid Build Coastguard Worker 		for (n = 0; n < 8; n++) utf8_buf[n] = 0;
166*c14be686SAndroid Build Coastguard Worker 
167*c14be686SAndroid Build Coastguard Worker 		utf32SourceStart = utf32_buf; utf32TargetStart = utf32_result;
168*c14be686SAndroid Build Coastguard Worker 		utf16TargetStart = utf16SourceStart = utf16_buf;
169*c14be686SAndroid Build Coastguard Worker 		utf8TargetStart = utf8SourceStart = utf8_buf;
170*c14be686SAndroid Build Coastguard Worker 
171*c14be686SAndroid Build Coastguard Worker 		/*
172*c14be686SAndroid Build Coastguard Worker 		 * Test UTF32 -> UTF16
173*c14be686SAndroid Build Coastguard Worker 		 */
174*c14be686SAndroid Build Coastguard Worker 		result = ConvertUTF32toUTF16((const UTF32 **) &utf32SourceStart, &(utf32_buf[1]), &utf16TargetStart, &(utf16_buf[2]), strictConversion);
175*c14be686SAndroid Build Coastguard Worker 		if (i < UNI_SUR_HIGH_START || i > UNI_SUR_LOW_END) {
176*c14be686SAndroid Build Coastguard Worker 			/* skip result checking for all but 0000d800, which we know to be illegal */
177*c14be686SAndroid Build Coastguard Worker 			switch (result) {
178*c14be686SAndroid Build Coastguard Worker 			default: fprintf(stderr, "Test02A fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
179*c14be686SAndroid Build Coastguard Worker 			case conversionOK: break;
180*c14be686SAndroid Build Coastguard Worker 			case sourceExhausted: printf("sourceExhausted\t"); break;
181*c14be686SAndroid Build Coastguard Worker 			case targetExhausted: printf("targetExhausted\t"); break;
182*c14be686SAndroid Build Coastguard Worker 			case sourceIllegal: printf("sourceIllegal\t"); break;
183*c14be686SAndroid Build Coastguard Worker 		    }
184*c14be686SAndroid Build Coastguard Worker 		}
185*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
186*c14be686SAndroid Build Coastguard Worker 			if (i <= UNI_SUR_HIGH_START || i > UNI_SUR_LOW_END) {
187*c14be686SAndroid Build Coastguard Worker 				printf("Test02A for %d, input %08x, output %04x,%04x, result %d\n",
188*c14be686SAndroid Build Coastguard Worker 				    i, utf32_buf[0], utf16_buf[0], utf16_buf[1], result);
189*c14be686SAndroid Build Coastguard Worker 				if ((i != UNI_SUR_HIGH_START) || (result != sourceIllegal)) {
190*c14be686SAndroid Build Coastguard Worker 					return 0;
191*c14be686SAndroid Build Coastguard Worker 				} else {
192*c14be686SAndroid Build Coastguard Worker 					printf("!!! Test02A: note expected illegal result for 0x0000D800\n");
193*c14be686SAndroid Build Coastguard Worker 				}
194*c14be686SAndroid Build Coastguard Worker 			}
195*c14be686SAndroid Build Coastguard Worker 		}
196*c14be686SAndroid Build Coastguard Worker 		if (i > UNI_SUR_HIGH_START && i <= UNI_SUR_LOW_END) continue;
197*c14be686SAndroid Build Coastguard Worker 
198*c14be686SAndroid Build Coastguard Worker 		/*
199*c14be686SAndroid Build Coastguard Worker 		 * Test UTF16 -> UTF8, with legality check on.  We check for everything except
200*c14be686SAndroid Build Coastguard Worker 		 * for unpaired low surrogates.  We do make one check that the lowest low
201*c14be686SAndroid Build Coastguard Worker 		 * surrogate, when unpaired, is illegal.
202*c14be686SAndroid Build Coastguard Worker 		 */
203*c14be686SAndroid Build Coastguard Worker 		result = ConvertUTF16toUTF8((const UTF16 **) &utf16SourceStart, &(utf16_buf[2]), &utf8TargetStart, &(utf8_buf[7]), strictConversion);
204*c14be686SAndroid Build Coastguard Worker 		switch (result) {
205*c14be686SAndroid Build Coastguard Worker 		default: fprintf(stderr, "Test02B fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
206*c14be686SAndroid Build Coastguard Worker 		case conversionOK: break;
207*c14be686SAndroid Build Coastguard Worker 		case sourceExhausted: printf("sourceExhausted\t"); break;
208*c14be686SAndroid Build Coastguard Worker 		case targetExhausted: printf("targetExhausted\t"); break;
209*c14be686SAndroid Build Coastguard Worker 		case sourceIllegal: printf("sourceIllegal\t"); break;
210*c14be686SAndroid Build Coastguard Worker 		}
211*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
212*c14be686SAndroid Build Coastguard Worker 			printf("Test02B for %d (0x%x), input %04x,%04x; output %s; result %d\n",
213*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf16_buf[0], utf16_buf[1], utf8_buf, result);
214*c14be686SAndroid Build Coastguard Worker 			if ((i != UNI_SUR_LOW_START) && (i != UNI_SUR_HIGH_START)) {
215*c14be686SAndroid Build Coastguard Worker 				return 0;
216*c14be686SAndroid Build Coastguard Worker 			} else {
217*c14be686SAndroid Build Coastguard Worker 				/* Note: This illegal result only happens if we remove the surrogate
218*c14be686SAndroid Build Coastguard Worker 				    check in Test02A.  So it shouldn't be seen unless that check and
219*c14be686SAndroid Build Coastguard Worker 				    the "continue" are removed in the test above.
220*c14be686SAndroid Build Coastguard Worker 				*/
221*c14be686SAndroid Build Coastguard Worker 				if (i == UNI_SUR_LOW_START)
222*c14be686SAndroid Build Coastguard Worker 				    printf("!!! Test02B: note expected illegal result for 0xDC00,0000\n");
223*c14be686SAndroid Build Coastguard Worker 				else if (i == UNI_SUR_HIGH_START)
224*c14be686SAndroid Build Coastguard Worker 				    printf("!!! Test02B: note expected illegal result for 0xD800,0000\n");
225*c14be686SAndroid Build Coastguard Worker 			}
226*c14be686SAndroid Build Coastguard Worker 		}
227*c14be686SAndroid Build Coastguard Worker 		if ((i == UNI_SUR_LOW_START) && result != sourceIllegal) {
228*c14be686SAndroid Build Coastguard Worker 			printf("Test02B for %d (0x%x), input %04x,%04x; output %s; result %d\n",
229*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf16_buf[0], utf16_buf[1], utf8_buf, result);
230*c14be686SAndroid Build Coastguard Worker 				printf("Test02B: expected illegal result for 0xDC00,0000 was not flagged illegal.\n");
231*c14be686SAndroid Build Coastguard Worker 				return 0;
232*c14be686SAndroid Build Coastguard Worker 		}
233*c14be686SAndroid Build Coastguard Worker 
234*c14be686SAndroid Build Coastguard Worker 		if ((i >= UNI_SUR_HIGH_START) & (i <= UNI_SUR_LOW_END)) continue;
235*c14be686SAndroid Build Coastguard Worker 
236*c14be686SAndroid Build Coastguard Worker 		/*
237*c14be686SAndroid Build Coastguard Worker 		 * Reset some result buffer pointers for the trip back.
238*c14be686SAndroid Build Coastguard Worker 		 */
239*c14be686SAndroid Build Coastguard Worker 		utf32SourceStart = utf32_buf; utf32TargetStart = utf32_result;
240*c14be686SAndroid Build Coastguard Worker 		utf16TargetStart = utf16SourceStart = utf16_result;
241*c14be686SAndroid Build Coastguard Worker 		utf8TargetStart = utf8SourceStart = utf8_buf;
242*c14be686SAndroid Build Coastguard Worker 
243*c14be686SAndroid Build Coastguard Worker 		/*
244*c14be686SAndroid Build Coastguard Worker 		 * Test UTF8 -> UTF16, with legality check on.
245*c14be686SAndroid Build Coastguard Worker 		 */
246*c14be686SAndroid Build Coastguard Worker 		result = ConvertUTF8toUTF16((const UTF8 **) &utf8SourceStart, &(utf8_buf[trailingBytesForUTF8[utf8_buf[0]]+1]), &utf16TargetStart, &(utf16_result[2]), strictConversion);
247*c14be686SAndroid Build Coastguard Worker 		switch (result) {
248*c14be686SAndroid Build Coastguard Worker 		default: fprintf(stderr, "Test02C fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
249*c14be686SAndroid Build Coastguard Worker 		case conversionOK: break;
250*c14be686SAndroid Build Coastguard Worker 		case sourceExhausted: printf("sourceExhausted\t"); break;
251*c14be686SAndroid Build Coastguard Worker 		case targetExhausted: printf("targetExhausted\t"); break;
252*c14be686SAndroid Build Coastguard Worker 		case sourceIllegal: printf("sourceIllegal\t"); break;
253*c14be686SAndroid Build Coastguard Worker 		}
254*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
255*c14be686SAndroid Build Coastguard Worker 			printf("Test02C for %d (0x%x), input %s; output %04x,%04x; result %d\n",
256*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf8_buf, utf16_buf[0], utf16_buf[1], result);
257*c14be686SAndroid Build Coastguard Worker 			return 0;
258*c14be686SAndroid Build Coastguard Worker 		}
259*c14be686SAndroid Build Coastguard Worker 		for (n = 0; n < 3; n++) { /* check that the utf16 result is the same as what went in. */
260*c14be686SAndroid Build Coastguard Worker 			if (utf16_buf[n] != utf16_result[n]) {
261*c14be686SAndroid Build Coastguard Worker 				printf("Test02C error: input = 0x%08x; utf16_buf = 0x%04x,0x%04x; utf16_result = 0x%04x,0x%04x\n",
262*c14be686SAndroid Build Coastguard Worker 					utf32_buf[0], utf16_buf[0], utf16_buf[1], utf16_result[0], utf16_result[1]);
263*c14be686SAndroid Build Coastguard Worker 				return 0;
264*c14be686SAndroid Build Coastguard Worker 			}
265*c14be686SAndroid Build Coastguard Worker 		}
266*c14be686SAndroid Build Coastguard Worker 
267*c14be686SAndroid Build Coastguard Worker 		/*
268*c14be686SAndroid Build Coastguard Worker 		 * Test UTF16 -> UTF32, with legality check on.  If the result of our previous
269*c14be686SAndroid Build Coastguard Worker 		 * conversion gave us a "surrogate pair", then we need to convert 2 entities
270*c14be686SAndroid Build Coastguard Worker 		 * back to UTF32.
271*c14be686SAndroid Build Coastguard Worker 		 */
272*c14be686SAndroid Build Coastguard Worker 		if (utf16_result[0] >= UNI_SUR_HIGH_START && utf16_result[0] <= UNI_SUR_HIGH_END) {
273*c14be686SAndroid Build Coastguard Worker 			result = ConvertUTF16toUTF32((const UTF16 **) &utf16SourceStart, &(utf16_result[2]), &utf32TargetStart, &(utf32_result[1]), strictConversion);
274*c14be686SAndroid Build Coastguard Worker 		} else {
275*c14be686SAndroid Build Coastguard Worker 			result = ConvertUTF16toUTF32((const UTF16 **) &utf16SourceStart, &(utf16_result[1]), &utf32TargetStart, &(utf32_result[1]), strictConversion);
276*c14be686SAndroid Build Coastguard Worker 		}
277*c14be686SAndroid Build Coastguard Worker 		switch (result) {
278*c14be686SAndroid Build Coastguard Worker 		default: fprintf(stderr, "Test02D fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
279*c14be686SAndroid Build Coastguard Worker 		case conversionOK: break;
280*c14be686SAndroid Build Coastguard Worker 		case sourceExhausted: printf("sourceExhausted\t"); break;
281*c14be686SAndroid Build Coastguard Worker 		case targetExhausted: printf("targetExhausted\t"); break;
282*c14be686SAndroid Build Coastguard Worker 		case sourceIllegal: printf("sourceIllegal\t"); break;
283*c14be686SAndroid Build Coastguard Worker 		}
284*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
285*c14be686SAndroid Build Coastguard Worker 			printf("Test02D for %d (0x%x), input %04x,%04x; output %08x; result %d\n",
286*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf16_buf[0], utf16_buf[1], utf32_result[0], result);
287*c14be686SAndroid Build Coastguard Worker 			return 0;
288*c14be686SAndroid Build Coastguard Worker 		}
289*c14be686SAndroid Build Coastguard Worker 
290*c14be686SAndroid Build Coastguard Worker 		/*
291*c14be686SAndroid Build Coastguard Worker 		 * Now, check the final round-trip value.
292*c14be686SAndroid Build Coastguard Worker 		 */
293*c14be686SAndroid Build Coastguard Worker 		if (utf32_buf[0] != utf32_result[0]) {
294*c14be686SAndroid Build Coastguard Worker 			printf("Test02E for %d: utf32 input %08x; trip output %08x (utf_16buf is %04x,%04x)\n", i, utf32_buf[0], utf32_result[0], utf16_buf[0], utf16_buf[1]);
295*c14be686SAndroid Build Coastguard Worker 			return 0;
296*c14be686SAndroid Build Coastguard Worker 		}
297*c14be686SAndroid Build Coastguard Worker 	}
298*c14be686SAndroid Build Coastguard Worker 	return 1;
299*c14be686SAndroid Build Coastguard Worker }
300*c14be686SAndroid Build Coastguard Worker 
301*c14be686SAndroid Build Coastguard Worker /* ---------------------------------------------------------------------
302*c14be686SAndroid Build Coastguard Worker 	test03 - Test round trip UTF32 -> UTF8 -> UTF32
303*c14be686SAndroid Build Coastguard Worker 
304*c14be686SAndroid Build Coastguard Worker 	This tests the functions that were not tested by test02 above.
305*c14be686SAndroid Build Coastguard Worker 	For each UTF32 value 0 through 0x10FFFF, it tests the conversion
306*c14be686SAndroid Build Coastguard Worker 	to UTF-8 and back.  The test is exhaustive.
307*c14be686SAndroid Build Coastguard Worker 
308*c14be686SAndroid Build Coastguard Worker    --------------------------------------------------------------------- */
309*c14be686SAndroid Build Coastguard Worker 
test03()310*c14be686SAndroid Build Coastguard Worker int test03() {
311*c14be686SAndroid Build Coastguard Worker 	int i, n;
312*c14be686SAndroid Build Coastguard Worker 	ConversionResult result;
313*c14be686SAndroid Build Coastguard Worker 	UTF32 utf32_buf[2], utf32_result[2];
314*c14be686SAndroid Build Coastguard Worker 	UTF8 utf8_buf[8];
315*c14be686SAndroid Build Coastguard Worker 	UTF32 *utf32SourceStart, *utf32TargetStart;
316*c14be686SAndroid Build Coastguard Worker 	UTF8 *utf8SourceStart, *utf8TargetStart;
317*c14be686SAndroid Build Coastguard Worker 
318*c14be686SAndroid Build Coastguard Worker 	printf("Begin Test03\n"); fflush(stdout);
319*c14be686SAndroid Build Coastguard Worker 
320*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i <= 0x10FFFF; i++) {
321*c14be686SAndroid Build Coastguard Worker 		/* Skip all surrogates except UNI_SUR_HIGH_START, which we test for illegality. */
322*c14be686SAndroid Build Coastguard Worker 		if (i > UNI_SUR_HIGH_START && i <= UNI_SUR_LOW_END) continue;
323*c14be686SAndroid Build Coastguard Worker 
324*c14be686SAndroid Build Coastguard Worker 		utf32_buf[0] = i; utf32_buf[1] = 0;
325*c14be686SAndroid Build Coastguard Worker 		utf32_result[0] = utf32_result[1] = 0;
326*c14be686SAndroid Build Coastguard Worker 		for (n = 0; n < 8; n++) utf8_buf[n] = 0;
327*c14be686SAndroid Build Coastguard Worker 
328*c14be686SAndroid Build Coastguard Worker 		utf32SourceStart = utf32_buf; utf32TargetStart = utf32_result;
329*c14be686SAndroid Build Coastguard Worker 		utf8TargetStart = utf8SourceStart = utf8_buf;
330*c14be686SAndroid Build Coastguard Worker 
331*c14be686SAndroid Build Coastguard Worker 		/*
332*c14be686SAndroid Build Coastguard Worker 		 * Test UTF32 -> UTF8, with legality check on.
333*c14be686SAndroid Build Coastguard Worker 		 */
334*c14be686SAndroid Build Coastguard Worker 		result = ConvertUTF32toUTF8((const UTF32 **) &utf32SourceStart, &(utf32_buf[1]), & utf8TargetStart, &(utf8_buf[7]), strictConversion);
335*c14be686SAndroid Build Coastguard Worker 		switch (result) {
336*c14be686SAndroid Build Coastguard Worker 		default: fprintf(stderr, "Test03A fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
337*c14be686SAndroid Build Coastguard Worker 		case conversionOK: break;
338*c14be686SAndroid Build Coastguard Worker 		case sourceExhausted: printf("sourceExhausted\t"); break;
339*c14be686SAndroid Build Coastguard Worker 		case targetExhausted: printf("targetExhausted\t"); break;
340*c14be686SAndroid Build Coastguard Worker 		case sourceIllegal: printf("sourceIllegal\t"); break;
341*c14be686SAndroid Build Coastguard Worker 		}
342*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
343*c14be686SAndroid Build Coastguard Worker 			printf("Test03A for %d (0x%x); output %s; result %d\n",
344*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf8_buf, result);
345*c14be686SAndroid Build Coastguard Worker 			if (i != UNI_SUR_HIGH_START) {
346*c14be686SAndroid Build Coastguard Worker 				return 0;
347*c14be686SAndroid Build Coastguard Worker 			} else {
348*c14be686SAndroid Build Coastguard Worker 				printf("!!! Test03A: note expected illegal result for 0x0000D800\n");
349*c14be686SAndroid Build Coastguard Worker 			}
350*c14be686SAndroid Build Coastguard Worker 		}
351*c14be686SAndroid Build Coastguard Worker 		if ((i == UNI_SUR_HIGH_START) && result != sourceIllegal) {
352*c14be686SAndroid Build Coastguard Worker 			printf("Test03A for %d (0x%x); output %s; result %d\n",
353*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf8_buf, result);
354*c14be686SAndroid Build Coastguard Worker 				printf("Test03A: expected illegal result for 0x0000D800 was not flagged illegal.\n");
355*c14be686SAndroid Build Coastguard Worker 				return 0;
356*c14be686SAndroid Build Coastguard Worker 		}
357*c14be686SAndroid Build Coastguard Worker 
358*c14be686SAndroid Build Coastguard Worker 		if ((i >= UNI_SUR_HIGH_START) & (i <= UNI_SUR_LOW_END)) continue;
359*c14be686SAndroid Build Coastguard Worker 
360*c14be686SAndroid Build Coastguard Worker 		/*
361*c14be686SAndroid Build Coastguard Worker 		 * Reset some result buffer pointers for the trip back.
362*c14be686SAndroid Build Coastguard Worker 		 */
363*c14be686SAndroid Build Coastguard Worker 		utf32SourceStart = utf32_buf; utf32TargetStart = utf32_result;
364*c14be686SAndroid Build Coastguard Worker 		utf8TargetStart = utf8SourceStart = utf8_buf;
365*c14be686SAndroid Build Coastguard Worker 
366*c14be686SAndroid Build Coastguard Worker 		/*
367*c14be686SAndroid Build Coastguard Worker 		 * Test UTF8 -> UTF32, with legality check on.
368*c14be686SAndroid Build Coastguard Worker 		 */
369*c14be686SAndroid Build Coastguard Worker 		result = ConvertUTF8toUTF32((const UTF8 **) &utf8SourceStart, &(utf8_buf[trailingBytesForUTF8[utf8_buf[0]]+1]), &utf32TargetStart, &(utf32_result[1]), strictConversion);
370*c14be686SAndroid Build Coastguard Worker 		switch (result) {
371*c14be686SAndroid Build Coastguard Worker 		default: fprintf(stderr, "Test03B fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
372*c14be686SAndroid Build Coastguard Worker 		case conversionOK: break;
373*c14be686SAndroid Build Coastguard Worker 		case sourceExhausted: printf("sourceExhausted\t"); break;
374*c14be686SAndroid Build Coastguard Worker 		case targetExhausted: printf("targetExhausted\t"); break;
375*c14be686SAndroid Build Coastguard Worker 		case sourceIllegal: printf("sourceIllegal\t"); break;
376*c14be686SAndroid Build Coastguard Worker 		}
377*c14be686SAndroid Build Coastguard Worker 		if (result != conversionOK) {
378*c14be686SAndroid Build Coastguard Worker 			printf("Test03B for %d (0x%x), input %s; output 0x%08x; result %d\n",
379*c14be686SAndroid Build Coastguard Worker 				i, utf32_buf[0], utf8_buf, utf32_result[0], result);
380*c14be686SAndroid Build Coastguard Worker 			return 0;
381*c14be686SAndroid Build Coastguard Worker 		}
382*c14be686SAndroid Build Coastguard Worker 
383*c14be686SAndroid Build Coastguard Worker 		/*
384*c14be686SAndroid Build Coastguard Worker 		 * Now, check the final round-trip value.
385*c14be686SAndroid Build Coastguard Worker 		 */
386*c14be686SAndroid Build Coastguard Worker 		if (utf32_buf[0] != utf32_result[0]) {
387*c14be686SAndroid Build Coastguard Worker 			printf("Test03C for %d: utf32 input %08x; utf8 buf %s; trip output %08x\n", i, utf32_buf[0], utf8_buf, utf32_result[0]);
388*c14be686SAndroid Build Coastguard Worker 			return 0;
389*c14be686SAndroid Build Coastguard Worker 		}
390*c14be686SAndroid Build Coastguard Worker 	}
391*c14be686SAndroid Build Coastguard Worker 	return 1;
392*c14be686SAndroid Build Coastguard Worker }
393*c14be686SAndroid Build Coastguard Worker 
394*c14be686SAndroid Build Coastguard Worker /* ---------------------------------------------------------------------
395*c14be686SAndroid Build Coastguard Worker 	test04 - Test an illegal UTF-32 value > 10FFFF conversion to UTF-8.
396*c14be686SAndroid Build Coastguard Worker 	Expect it will be turned into UNI_REPLACEMENT_CHAR.
397*c14be686SAndroid Build Coastguard Worker 
398*c14be686SAndroid Build Coastguard Worker    --------------------------------------------------------------------- */
399*c14be686SAndroid Build Coastguard Worker 
test04()400*c14be686SAndroid Build Coastguard Worker int test04() {
401*c14be686SAndroid Build Coastguard Worker 	int i, n;
402*c14be686SAndroid Build Coastguard Worker 	ConversionResult result;
403*c14be686SAndroid Build Coastguard Worker 	UTF32 utf32_buf[2];
404*c14be686SAndroid Build Coastguard Worker 	UTF8 utf8_buf[8];
405*c14be686SAndroid Build Coastguard Worker 	UTF32 *utf32SourceStart, *utf32TargetStart;
406*c14be686SAndroid Build Coastguard Worker 	UTF8 *utf8SourceStart, *utf8TargetStart;
407*c14be686SAndroid Build Coastguard Worker 
408*c14be686SAndroid Build Coastguard Worker 	printf("Begin Test04\n"); fflush(stdout);
409*c14be686SAndroid Build Coastguard Worker 
410*c14be686SAndroid Build Coastguard Worker 	i = 0x10FFFF + 21; /* an arbitrary value > legal */
411*c14be686SAndroid Build Coastguard Worker 
412*c14be686SAndroid Build Coastguard Worker 	utf32_buf[0] = i; utf32_buf[1] = 0;
413*c14be686SAndroid Build Coastguard Worker 	for (n = 0; n < 8; n++) utf8_buf[n] = 0;
414*c14be686SAndroid Build Coastguard Worker 
415*c14be686SAndroid Build Coastguard Worker 	utf32SourceStart = utf32_buf;
416*c14be686SAndroid Build Coastguard Worker 	utf8TargetStart = utf8_buf;
417*c14be686SAndroid Build Coastguard Worker 
418*c14be686SAndroid Build Coastguard Worker 	/*
419*c14be686SAndroid Build Coastguard Worker 	 * Test UTF32 -> UTF8, with legality check on.
420*c14be686SAndroid Build Coastguard Worker 	 */
421*c14be686SAndroid Build Coastguard Worker 	result = ConvertUTF32toUTF8((const UTF32 **) &utf32SourceStart, &(utf32_buf[1]), & utf8TargetStart, &(utf8_buf[7]), strictConversion);
422*c14be686SAndroid Build Coastguard Worker 	if (result != sourceIllegal) {
423*c14be686SAndroid Build Coastguard Worker 		fprintf(stderr, "Test04A fatal error: result %d for input %08x\n", result, utf32_buf[0]); exit(1);
424*c14be686SAndroid Build Coastguard Worker 	}
425*c14be686SAndroid Build Coastguard Worker 
426*c14be686SAndroid Build Coastguard Worker 	return 1;
427*c14be686SAndroid Build Coastguard Worker }
428*c14be686SAndroid Build Coastguard Worker 
429*c14be686SAndroid Build Coastguard Worker /* --------------------------------------------------------------------- */
430*c14be686SAndroid Build Coastguard Worker 
main()431*c14be686SAndroid Build Coastguard Worker int main() {
432*c14be686SAndroid Build Coastguard Worker 	printf("Three tests of round-trip conversions will be performed.\n");
433*c14be686SAndroid Build Coastguard Worker 	printf("One test of illegal UTF-32 will be peroformed.\n");
434*c14be686SAndroid Build Coastguard Worker 	printf("Two illegal result messages are expected; one in test 02A; one in test 03A.\n");
435*c14be686SAndroid Build Coastguard Worker 	printf("These are for tests of Surrogate conversion.\n\n");
436*c14be686SAndroid Build Coastguard Worker 	fflush(stdout);
437*c14be686SAndroid Build Coastguard Worker 	if (test01()) {	printf("******** Test01 succeeded without error. ********\n\n"); }
438*c14be686SAndroid Build Coastguard Worker 	else { printf("-------- Test01 failed. --------\n\n"); }
439*c14be686SAndroid Build Coastguard Worker 	if (test02()) { printf("******** Test02 succeeded without error. ********\n\n"); }
440*c14be686SAndroid Build Coastguard Worker 	else { printf("-------- Test02 failed. --------\n\n"); }
441*c14be686SAndroid Build Coastguard Worker 	if (test03()) { printf("******** Test03 succeeded without error. ********\n\n"); }
442*c14be686SAndroid Build Coastguard Worker 	else { printf("-------- Test03 failed. --------\n\n"); }
443*c14be686SAndroid Build Coastguard Worker 	if (test04()) { printf("******** Test04 succeeded without error. ********\n\n"); }
444*c14be686SAndroid Build Coastguard Worker 	else { printf("-------- Test04 failed. --------\n\n"); }
445*c14be686SAndroid Build Coastguard Worker 	return 0;
446*c14be686SAndroid Build Coastguard Worker }
447