1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * COPYRIGHT:
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (c) 1997-2010, International Business Machines Corporation and
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************/
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************************
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File CNORMTST.C
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History:
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*        Name                     Description
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     Madhu Katragadda            Ported for C API
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     synwee                      added test for quick check
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     synwee                      added test for checkFCD
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*********************************************************************************/
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*tests for u_normalization*/
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/unorm.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cintltst.h"
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if UCONFIG_NO_NORMALIZATION
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void addNormTest(TestNode** root) {
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* no normalization - nothing to do */
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h>
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <time.h>
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uchar.h"
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h"
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/unorm.h"
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cnormtst.h"
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof ((array)[0]))
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestAPI(void);
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestNormCoverage(void);
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestConcatenate(void);
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestNextPrevious(void);
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestIsNormalized(void);
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestFCNFKCClosure(void);
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestQuickCheckPerCP(void);
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestComposition(void);
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestFCD(void);
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestGetDecomposition(void);
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char* const canonTests[][3] = {
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Input*/                    /*Decomposed*/                /*Composed*/
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "cat",                    "cat",                        "cat"                    },
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00e0ardvark",            "a\\u0300ardvark",            "\\u00e0ardvark",        },
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u1e0a",                "D\\u0307",                    "\\u1e0a"                }, /* D-dot_above*/
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "D\\u0307",                "D\\u0307",                    "\\u1e0a"                }, /* D dot_above*/
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u1e0c\\u0307",            "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D-dot_below dot_above*/
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u1e0a\\u0323",            "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D-dot_above dot_below */
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "D\\u0307\\u0323",        "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D dot_below dot_above */
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u1e10\\u0307\\u0323",    "D\\u0327\\u0323\\u0307",    "\\u1e10\\u0323\\u0307"    }, /*D dot_below cedilla dot_above*/
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "D\\u0307\\u0328\\u0323",    "D\\u0328\\u0323\\u0307",    "\\u1e0c\\u0328\\u0307"    }, /* D dot_above ogonek dot_below*/
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u1E14",                "E\\u0304\\u0300",            "\\u1E14"                }, /* E-macron-grave*/
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u0112\\u0300",            "E\\u0304\\u0300",            "\\u1E14"                }, /* E-macron + grave*/
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00c8\\u0304",            "E\\u0300\\u0304",            "\\u00c8\\u0304"        }, /* E-grave + macron*/
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u212b",                "A\\u030a",                    "\\u00c5"                }, /* angstrom_sign*/
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00c5",                "A\\u030a",                    "\\u00c5"                }, /* A-ring*/
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00C4ffin",            "A\\u0308ffin",                "\\u00C4ffin"                    },
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00C4\\uFB03n",        "A\\u0308\\uFB03n",            "\\u00C4\\uFB03n"                },
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "Henry IV",                "Henry IV",                    "Henry IV"                },
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "Henry \\u2163",            "Henry \\u2163",            "Henry \\u2163"            },
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AC",                "\\u30AB\\u3099",            "\\u30AC"                }, /* ga (Katakana)*/
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AB\\u3099",            "\\u30AB\\u3099",            "\\u30AC"                }, /*ka + ten*/
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\uFF76\\uFF9E",            "\\uFF76\\uFF9E",            "\\uFF76\\uFF9E"        }, /* hw_ka + hw_ten*/
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AB\\uFF9E",            "\\u30AB\\uFF9E",            "\\u30AB\\uFF9E"        }, /* ka + hw_ten*/
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\uFF76\\u3099",            "\\uFF76\\u3099",            "\\uFF76\\u3099"        },  /* hw_ka + ten*/
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "A\\u0300\\u0316",           "A\\u0316\\u0300",           "\\u00C0\\u0316"        },  /* hw_ka + ten*/
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "", "", "" }
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char* const compatTests[][3] = {
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Input*/                        /*Decomposed    */                /*Composed*/
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "cat",                        "cat",                            "cat"                },
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\uFB4f",                    "\\u05D0\\u05DC",                "\\u05D0\\u05DC"    }, /* Alef-Lamed vs. Alef, Lamed*/
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00C4ffin",                "A\\u0308ffin",                    "\\u00C4ffin"             },
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u00C4\\uFB03n",            "A\\u0308ffin",                    "\\u00C4ffin"                }, /* ffi ligature -> f + f + i*/
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "Henry IV",                    "Henry IV",                        "Henry IV"            },
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "Henry \\u2163",                "Henry IV",                        "Henry IV"            },
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AC",                    "\\u30AB\\u3099",                "\\u30AC"            }, /* ga (Katakana)*/
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AB\\u3099",                "\\u30AB\\u3099",                "\\u30AC"            }, /*ka + ten*/
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\uFF76\\u3099",                "\\u30AB\\u3099",                "\\u30AC"            }, /* hw_ka + ten*/
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later*/
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\uFF76\\uFF9E",                "\\u30AB\\u3099",                "\\u30AC"            }, /* hw_ka + hw_ten*/
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u30AB\\uFF9E",                "\\u30AB\\u3099",                "\\u30AC"            }, /* ka + hw_ten*/
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "", "", "" }
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char* const fcdTests[][3] = {
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Added for testing the below-U+0300 prefix of a NUL-terminated string. */
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u010e\\u0327", "D\\u0327\\u030c", NULL },  /* D-caron + cedilla */
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { "\\u010e", "\\u010e", NULL }  /* D-caron */
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void addNormTest(TestNode** root);
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void addNormTest(TestNode** root)
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestAPI, "tsnorm/cnormtst/TestAPI");
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestDecomp, "tsnorm/cnormtst/TestDecomp");
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestCompatDecomp, "tsnorm/cnormtst/TestCompatDecomp");
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestCanonDecompCompose, "tsnorm/cnormtst/TestCanonDecompCompose");
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestCompatDecompCompose, "tsnorm/cnormtst/TestCompatDecompCompose");
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestFCD, "tsnorm/cnormtst/TestFCD");
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestNull, "tsnorm/cnormtst/TestNull");
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestQuickCheck, "tsnorm/cnormtst/TestQuickCheck");
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestQuickCheckPerCP, "tsnorm/cnormtst/TestQuickCheckPerCP");
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestIsNormalized, "tsnorm/cnormtst/TestIsNormalized");
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestCheckFCD, "tsnorm/cnormtst/TestCheckFCD");
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestNormCoverage, "tsnorm/cnormtst/TestNormCoverage");
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestConcatenate, "tsnorm/cnormtst/TestConcatenate");
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestNextPrevious, "tsnorm/cnormtst/TestNextPrevious");
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestFCNFKCClosure, "tsnorm/cnormtst/TestFCNFKCClosure");
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestComposition, "tsnorm/cnormtst/TestComposition");
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestGetDecomposition, "tsnorm/cnormtst/TestGetDecomposition");
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char* const modeStrings[]={
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_NONE",
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_NFD",
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_NFKD",
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_NFC",
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_NFKC",
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_FCD",
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "UNORM_MODE_COUNT"
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestNormCases(UNormalizationMode mode,
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          const char* const cases[][3], int32_t lengthOfCases) {
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t x, neededLen, length2;
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t expIndex= (mode==UNORM_NFC || mode==UNORM_NFKC) ? 2 : 1;
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar *source=NULL;
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar result[16];
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_verbose("Testing unorm_normalize(%s)\n", modeStrings[mode]);
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(x=0; x < lengthOfCases; x++)
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UErrorCode status = U_ZERO_ERROR, status2 = U_ZERO_ERROR;
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        source=CharsToUChars(cases[x][0]);
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        neededLen= unorm_normalize(source, u_strlen(source), mode, 0, NULL, 0, &status);
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length2= unorm_normalize(source, -1, mode, 0, NULL, 0, &status2);
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(neededLen!=length2) {
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          log_err("ERROR in unorm_normalize(%s)[%d]: "
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  "preflight length/NUL %d!=%d preflight length/srcLength\n",
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  modeStrings[mode], (int)x, (int)neededLen, (int)length2);
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(status==U_BUFFER_OVERFLOW_ERROR)
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status=U_ZERO_ERROR;
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length2=unorm_normalize(source, u_strlen(source), mode, 0, result, LENGTHOF(result), &status);
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(status) || neededLen!=length2) {
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("ERROR in unorm_normalize(%s/NUL) at %s:  %s - (Are you missing data?)\n",
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         modeStrings[mode], austrdup(source), myErrorName(status));
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            assertEqual(result, cases[x][expIndex], x);
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length2=unorm_normalize(source, -1, mode, 0, result, LENGTHOF(result), &status);
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(status) || neededLen!=length2) {
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("ERROR in unorm_normalize(%s/srcLength) at %s:  %s - (Are you missing data?)\n",
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         modeStrings[mode], austrdup(source), myErrorName(status));
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            assertEqual(result, cases[x][expIndex], x);
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        free(source);
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestDecomp() {
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNormCases(UNORM_NFD, canonTests, LENGTHOF(canonTests));
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestCompatDecomp() {
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNormCases(UNORM_NFKD, compatTests, LENGTHOF(compatTests));
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestCanonDecompCompose() {
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNormCases(UNORM_NFC, canonTests, LENGTHOF(canonTests));
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestCompatDecompCompose() {
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNormCases(UNORM_NFKC, compatTests, LENGTHOF(compatTests));
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestFCD() {
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNormCases(UNORM_FCD, fcdTests, LENGTHOF(fcdTests));
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void assertEqual(const UChar* result, const char* expected, int32_t index)
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar *expectedUni = CharsToUChars(expected);
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(u_strcmp(result, expectedUni)!=0){
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("ERROR in decomposition at index = %d. EXPECTED: %s , GOT: %s\n", index, expected,
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            austrdup(result) );
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(expectedUni);
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestNull_check(UChar *src, int32_t srcLen,
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UChar *exp, int32_t expLen,
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UNormalizationMode mode,
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    const char *name)
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t len, i;
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar   result[50];
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    status = U_ZERO_ERROR;
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0;i<50;i++)
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      {
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        result[i] = 0xFFFD;
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    len = unorm_normalize(src, srcLen, mode, 0, result, 50, &status);
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("unorm_normalize(%s) with 0x0000 failed: %s - (Are you missing data?)\n", name, u_errorName(status));
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (len != expLen) {
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("unorm_normalize(%s) with 0x0000 failed: Expected len %d, got %d\n", name, expLen, len);
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      for(i=0;i<len;i++){
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(exp[i] != result[i]) {
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          log_err("unorm_normalize(%s): @%d, expected \\u%04X got \\u%04X\n",
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  name,
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  i,
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  exp[i],
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  result[i]);
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          return;
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_verbose("     %d: \\u%04X\n", i, result[i]);
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_verbose("unorm_normalize(%s) with 0x0000: OK\n", name);
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestNull()
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar   source_comp[] = { 0x0061, 0x0000, 0x0044, 0x0307 };
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t source_comp_len = 4;
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar   expect_comp[] = { 0x0061, 0x0000, 0x1e0a };
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t expect_comp_len = 3;
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar   source_dcmp[] = { 0x1e0A, 0x0000, 0x0929 };
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t source_dcmp_len = 3;
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar   expect_dcmp[] = { 0x0044, 0x0307, 0x0000, 0x0928, 0x093C };
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t expect_dcmp_len = 5;
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNull_check(source_comp,
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   source_comp_len,
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_comp,
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_comp_len,
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   UNORM_NFC,
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   "UNORM_NFC");
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNull_check(source_dcmp,
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   source_dcmp_len,
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_dcmp,
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_dcmp_len,
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   UNORM_NFD,
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   "UNORM_NFD");
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNull_check(source_comp,
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   source_comp_len,
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_comp,
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   expect_comp_len,
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   UNORM_NFKC,
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   "UNORM_NFKC");
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestQuickCheckResultNO()
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFD[] = {0x00C5, 0x0407, 0x1E00, 0x1F57, 0x220C,
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x30AE, 0xAC00, 0xD7A3, 0xFB36, 0xFB4E};
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFC[] = {0x0340, 0x0F93, 0x1F77, 0x1FBB, 0x1FEB,
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          0x2000, 0x232A, 0xF900, 0xFA1E, 0xFB4E};
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFKD[] = {0x00A0, 0x02E4, 0x1FDB, 0x24EA, 0x32FE,
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           0xAC00, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D};
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFKC[] = {0x00A0, 0x017F, 0x2000, 0x24EA, 0x32FE,
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           0x33FE, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D};
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const int SIZE = 10;
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int count = 0;
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode error = U_ZERO_ERROR;
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (; count < SIZE; count ++)
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) !=
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                              UNORM_NO)
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]);
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) !=
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                              UNORM_NO)
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]);
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) !=
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                              UNORM_NO)
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]);
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                              UNORM_NO)
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]);
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestQuickCheckResultYES()
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFD[] = {0x00C6, 0x017F, 0x0F74, 0x1000, 0x1E9A,
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x2261, 0x3075, 0x4000, 0x5000, 0xF000};
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFC[] = {0x0400, 0x0540, 0x0901, 0x1000, 0x1500,
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x1E9A, 0x3000, 0x4000, 0x5000, 0xF000};
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFKD[] = {0x00AB, 0x02A0, 0x1000, 0x1027, 0x2FFB,
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          0x3FFF, 0x4FFF, 0xA000, 0xF000, 0xFA27};
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFKC[] = {0x00B0, 0x0100, 0x0200, 0x0A02, 0x1000,
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          0x2010, 0x3030, 0x4000, 0xA000, 0xFA0E};
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const int SIZE = 10;
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int count = 0;
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode error = U_ZERO_ERROR;
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UChar cp = 0;
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  while (cp < 0xA0)
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&cp, 1, UNORM_NFD, &error) != UNORM_YES)
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("ERROR in NFD quick check at U+%04x - (Are you missing data?)\n", cp);
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&cp, 1, UNORM_NFC, &error) !=
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                             UNORM_YES)
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFC quick check at U+%04x\n", cp);
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&cp, 1, UNORM_NFKD, &error) != UNORM_YES)
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKD quick check at U+%04x\n", cp);
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&cp, 1, UNORM_NFKC, &error) !=
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                             UNORM_YES)
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKC quick check at U+%04x\n", cp);
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cp ++;
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (; count < SIZE; count ++)
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) !=
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                             UNORM_YES)
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]);
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error)
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                          != UNORM_YES)
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]);
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) !=
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                             UNORM_YES)
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]);
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                             UNORM_YES)
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]);
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestQuickCheckResultMAYBE()
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFC[] = {0x0306, 0x0654, 0x0BBE, 0x102E, 0x1161,
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x116A, 0x1173, 0x1175, 0x3099, 0x309A};
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const UChar CPNFKC[] = {0x0300, 0x0654, 0x0655, 0x09D7, 0x0B3E,
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          0x0DCF, 0xDDF, 0x102E, 0x11A8, 0x3099};
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const int SIZE = 10;
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int count = 0;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode error = U_ZERO_ERROR;
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* NFD and NFKD does not have any MAYBE codepoints */
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (; count < SIZE; count ++)
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) !=
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                           UNORM_MAYBE)
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("ERROR in NFC quick check at U+%04x - (Are you missing data?)\n", CPNFC[count]);
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                           UNORM_MAYBE)
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]);
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestQuickCheckStringResult()
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int count;
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UChar *d = NULL;
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UChar *c = NULL;
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode error = U_ZERO_ERROR;
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (count = 0; count < LENGTHOF(canonTests); count ++)
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    d = CharsToUChars(canonTests[count][1]);
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    c = CharsToUChars(canonTests[count][2]);
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(d, u_strlen(d), UNORM_NFD, &error) !=
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                            UNORM_YES)
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("ERROR in NFD quick check for string at count %d - (Are you missing data?)\n", count);
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(c, u_strlen(c), UNORM_NFC, &error) ==
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                            UNORM_NO)
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFC quick check for string at count %d\n", count);
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(d);
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(c);
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (count = 0; count < LENGTHOF(compatTests); count ++)
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    d = CharsToUChars(compatTests[count][1]);
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    c = CharsToUChars(compatTests[count][2]);
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(d, u_strlen(d), UNORM_NFKD, &error) !=
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                            UNORM_YES)
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKD quick check for string at count %d\n", count);
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(c, u_strlen(c), UNORM_NFKC, &error) !=
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                            UNORM_YES)
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("ERROR in NFKC quick check for string at count %d\n", count);
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(d);
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(c);
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestQuickCheck()
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  TestQuickCheckResultNO();
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  TestQuickCheckResultYES();
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  TestQuickCheckResultMAYBE();
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  TestQuickCheckStringResult();
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The intltest/NormalizerConformanceTest tests a lot of strings that _are_
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * normalized, and some that are not.
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Here we pick some specific cases and test the C API.
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestIsNormalized(void) {
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar notNFC[][8]={            /* strings that are not in NFC */
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x62, 0x61, 0x300, 0x63, 0 },         /* 0061 0300 compose */
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0xfb1d, 0 },                          /* excluded from composition */
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x0627, 0x0653, 0 },                  /* 0627 0653 compose */
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x3071, 0x306f, 0x309a, 0x3073, 0 }   /* 306F 309A compose */
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar notNFKC[][8]={           /* strings that are not in NFKC */
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x1100, 0x1161, 0 },                  /* Jamo compose */
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x1100, 0x314f, 0 },                  /* compatibility Jamo compose */
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x03b1, 0x1f00, 0x0345, 0x03b3, 0 }   /* 1F00 0345 compose */
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i;
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* API test */
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* normal case with length>=0 (length -1 used for special cases below) */
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!unorm_isNormalized(notNFC[0]+2, 1, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) {
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: !isNormalized(<U+0300>, NFC) (%s) - (Are you missing data?)\n", u_errorName(errorCode));
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* incoming U_FAILURE */
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_TRUNCATED_CHAR_FOUND;
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    (void)unorm_isNormalized(notNFC[0]+2, 1, UNORM_NFC, &errorCode);
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_TRUNCATED_CHAR_FOUND) {
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error: isNormalized(U_TRUNCATED_CHAR_FOUND) changed the error code to %s\n", u_errorName(errorCode));
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* NULL source */
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    (void)unorm_isNormalized(NULL, 1, UNORM_NFC, &errorCode);
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: isNormalized(NULL) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode));
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* bad length */
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    (void)unorm_isNormalized(notNFC[0]+2, -2, UNORM_NFC, &errorCode);
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: isNormalized([-2]) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode));
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* specific cases */
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<LENGTHOF(notNFC); ++i) {
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCode=U_ZERO_ERROR;
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(unorm_isNormalized(notNFC[i], -1, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) {
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("error: isNormalized(notNFC[%d], NFC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode));
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCode=U_ZERO_ERROR;
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(unorm_isNormalized(notNFC[i], -1, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) {
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("error: isNormalized(notNFC[%d], NFKC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode));
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<LENGTHOF(notNFKC); ++i) {
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCode=U_ZERO_ERROR;
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(unorm_isNormalized(notNFKC[i], -1, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) {
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("error: isNormalized(notNFKC[%d], NFKC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode));
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TestCheckFCD()
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UChar FAST_[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x0A};
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UChar FALSE_[] = {0x0001, 0x0002, 0x02EA, 0x03EB, 0x0300, 0x0301,
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          0x02B9, 0x0314, 0x0315, 0x0316};
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UChar TRUE_[] = {0x0030, 0x0040, 0x0440, 0x056D, 0x064F, 0x06E7,
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         0x0050, 0x0730, 0x09EE, 0x1E10};
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UChar datastr[][5] =
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  { {0x0061, 0x030A, 0x1E05, 0x0302, 0},
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {0x0061, 0x030A, 0x00E2, 0x0323, 0},
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {0x0061, 0x0323, 0x00E2, 0x0323, 0},
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {0x0061, 0x0323, 0x1E05, 0x0302, 0} };
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UBool result[] = {UNORM_YES, UNORM_NO, UNORM_NO, UNORM_YES};
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  static const UChar datachar[] = {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x6a,
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0xea,
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306,
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x0307, 0x0308, 0x0309, 0x030a,
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326,
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x0327, 0x0328, 0x0329, 0x032a,
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x1e00, 0x1e01, 0x1e02, 0x1e03, 0x1e04, 0x1e05, 0x1e06,
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            0x1e07, 0x1e08, 0x1e09, 0x1e0a};
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int count = 0;
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (unorm_quickCheck(FAST_, 10, UNORM_FCD, &status) != UNORM_YES)
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_data_err("unorm_quickCheck(FCD) failed: expected value for fast unorm_quickCheck is UNORM_YES - (Are you missing data?)\n");
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (unorm_quickCheck(FALSE_, 10, UNORM_FCD, &status) != UNORM_NO)
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("unorm_quickCheck(FCD) failed: expected value for error unorm_quickCheck is UNORM_NO\n");
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (unorm_quickCheck(TRUE_, 10, UNORM_FCD, &status) != UNORM_YES)
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_data_err("unorm_quickCheck(FCD) failed: expected value for correct unorm_quickCheck is UNORM_YES - (Are you missing data?)\n");
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (U_FAILURE(status))
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_data_err("unorm_quickCheck(FCD) failed: %s - (Are you missing data?)\n", u_errorName(status));
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  while (count < 4)
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool fcdresult = unorm_quickCheck(datastr[count], 4, UNORM_FCD, &status);
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("unorm_quickCheck(FCD) failed: exception occured at data set %d - (Are you missing data?)\n", count);
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      break;
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (result[count] != fcdresult) {
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm_quickCheck(FCD) failed: Data set %d expected value %d\n", count,
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 result[count]);
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    count ++;
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* random checks of long strings */
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  status = U_ZERO_ERROR;
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  srand((unsigned)time( NULL ));
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (count = 0; count < 50; count ++)
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int size = 0;
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool testresult = UNORM_YES;
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar data[20];
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar norm[100];
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar nfd[100];
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int normsize = 0;
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int nfdsize = 0;
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (size != 19) {
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      data[size] = datachar[(rand() * 50) / RAND_MAX];
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_verbose("0x%x", data[size]);
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      normsize += unorm_normalize(data + size, 1, UNORM_NFD, 0,
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  norm + normsize, 100 - normsize, &status);
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (U_FAILURE(status)) {
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("unorm_quickCheck(FCD) failed: exception occured at data generation - (Are you missing data?)\n");
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      size ++;
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_verbose("\n");
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfdsize = unorm_normalize(data, size, UNORM_NFD, 0,
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              nfd, 100, &status);
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("unorm_quickCheck(FCD) failed: exception occured at normalized data generation - (Are you missing data?)\n");
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (nfdsize != normsize || u_memcmp(nfd, norm, nfdsize) != 0) {
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      testresult = UNORM_NO;
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (testresult == UNORM_YES) {
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_verbose("result UNORM_YES\n");
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_verbose("result UNORM_NO\n");
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unorm_quickCheck(data, size, UNORM_FCD, &status) != testresult || U_FAILURE(status)) {
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_data_err("unorm_quickCheck(FCD) failed: expected %d for random data - (Are you missing data?)\n", testresult);
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestAPI() {
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar in[]={ 0x68, 0xe4 };
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar out[20]={ 0xffff, 0xffff, 0xffff, 0xffff };
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length;
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* try preflighting */
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(in, 2, UNORM_NFD, 0, NULL, 0, &errorCode);
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3) {
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("unorm_normalize(pure preflighting NFD)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(in, 2, UNORM_NFD, 0, out, 3, &errorCode);
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm_normalize(NFD)=%ld failed with %s\n", length, u_errorName(errorCode));
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(length!=3 || out[2]!=0x308 || out[3]!=0xffff) {
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm_normalize(NFD ma<umlaut>)=%ld failed with out[]=U+%04x U+%04x U+%04x U+%04x\n", length, out[0], out[1], out[2], out[3]);
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(NULL, 0, UNORM_NFC, 0, NULL, 0, &errorCode);
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm_normalize(src NULL[0], NFC, dest NULL[0])=%ld failed with %s\n", (long)length, u_errorName(errorCode));
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(NULL, 0, UNORM_NFC, 0, out, 20, &errorCode);
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm_normalize(src NULL[0], NFC, dest out[20])=%ld failed with %s\n", (long)length, u_errorName(errorCode));
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* test cases to improve test code coverage */
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)enum {
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_K_KIYEOK=0x3131,         /* NFKD->Jamo L U+1100 */
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_K_WEO=0x315d,            /* NFKD->Jamo V U+116f */
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_K_KIYEOK_SIOS=0x3133,    /* NFKD->Jamo T U+11aa */
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_KIYEOK=0x1100,           /* Jamo L U+1100 */
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_WEO=0x116f,              /* Jamo V U+116f */
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_KIYEOK_SIOS=0x11aa,      /* Jamo T U+11aa */
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_AC00=0xac00,             /* Hangul syllable = Jamo LV U+ac00 */
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANGUL_SYLLABLE=0xac00+14*28+3, /* Hangul syllable = U+1100 * U+116f * U+11aa */
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    MUSICAL_VOID_NOTEHEAD=0x1d157,
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    MUSICAL_HALF_NOTE=0x1d15e,  /* NFC/NFD->Notehead+Stem */
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    MUSICAL_STEM=0x1d165,       /* cc=216 */
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    MUSICAL_STACCATO=0x1d17c    /* cc=220 */
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestNormCoverage() {
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar input[1000], expect[1000], output[1000];
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i, length, inLength, expectLength, hangulPrefixLength, preflightLength;
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* create a long and nasty string with NFKC-unsafe characters */
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    inLength=0;
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* 3 Jamos L/V/T, all 8 combinations normal/compatibility */
766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK;
767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_WEO;
768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK_SIOS;
769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK;
771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_WEO;
772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK;
775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_WEO;
776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK_SIOS;
777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK;
779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_WEO;
780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_WEO;
784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK_SIOS;
785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_WEO;
788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_WEO;
792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK_SIOS;
793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_WEO;
796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Hangul LV with normal/compatibility Jamo T */
799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_AC00;
800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_KIYEOK_SIOS;
801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_AC00;
803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* compatibility Jamo L, V */
806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_WEO;
808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    hangulPrefixLength=inLength;
810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=UTF16_LEAD(MUSICAL_HALF_NOTE);
812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=UTF16_TRAIL(MUSICAL_HALF_NOTE);
813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<200; ++i) {
814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        input[inLength++]=UTF16_LEAD(MUSICAL_STACCATO);
815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        input[inLength++]=UTF16_TRAIL(MUSICAL_STACCATO);
816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        input[inLength++]=UTF16_LEAD(MUSICAL_STEM);
817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        input[inLength++]=UTF16_TRAIL(MUSICAL_STEM);
818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* (compatibility) Jamo L, T do not compose */
821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK;
822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    input[inLength++]=HANGUL_K_KIYEOK_SIOS;
823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* quick checks */
825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFD, &errorCode) || U_FAILURE(errorCode)) {
827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_quickCheck(long input, UNORM_NFD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode));
828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKD, &errorCode) || U_FAILURE(errorCode)) {
831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_quickCheck(long input, UNORM_NFKD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode));
832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) {
835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_quickCheck(long input, UNORM_NFC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode));
836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) {
839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_quickCheck(long input, UNORM_NFKC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode));
840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_FCD, &errorCode) || U_FAILURE(errorCode)) {
843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_quickCheck(long input, UNORM_FCD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode));
844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* NFKC */
847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expectLength=0;
848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_SYLLABLE;
863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_AC00+3;
865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_AC00+3;
867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_AC00+14*28;
869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_LEAD(MUSICAL_VOID_NOTEHEAD);
871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_TRAIL(MUSICAL_VOID_NOTEHEAD);
872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM);
873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM);
874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<200; ++i) {
875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM);
876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM);
877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<200; ++i) {
879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_LEAD(MUSICAL_STACCATO);
880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_TRAIL(MUSICAL_STACCATO);
881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_KIYEOK;
884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_KIYEOK_SIOS;
885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* try destination overflow first */
887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    preflightLength=unorm_normalize(input, inLength,
889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UNORM_NFKC, 0,
890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           output, 100, /* too short */
891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           &errorCode);
892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR) {
893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_normalize(long input, output too short, UNORM_NFKC) did not overflow but %s - (Are you missing data?)\n", u_errorName(errorCode));
894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* real NFKC */
897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(input, inLength,
899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UNORM_NFKC, 0,
900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           output, sizeof(output)/U_SIZEOF_UCHAR,
901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           &errorCode);
902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_normalize(long input, UNORM_NFKC) failed with %s - (Are you missing data?)\n", u_errorName(errorCode));
904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if(length!=expectLength || u_memcmp(output, expect, length)!=0) {
905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_normalize(long input, UNORM_NFKC) produced wrong result\n");
906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<length; ++i) {
907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(output[i]!=expect[i]) {
908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                log_err("    NFKC[%d]==U+%04lx expected U+%04lx\n", i, output[i], expect[i]);
909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(length!=preflightLength) {
914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_normalize(long input, UNORM_NFKC)==%ld but preflightLength==%ld\n", length, preflightLength);
915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* FCD */
918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    u_memcpy(expect, input, hangulPrefixLength);
919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expectLength=hangulPrefixLength;
920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_LEAD(MUSICAL_VOID_NOTEHEAD);
922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_TRAIL(MUSICAL_VOID_NOTEHEAD);
923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM);
924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM);
925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<200; ++i) {
926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM);
927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM);
928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<200; ++i) {
930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_LEAD(MUSICAL_STACCATO);
931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect[expectLength++]=UTF16_TRAIL(MUSICAL_STACCATO);
932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_K_KIYEOK;
935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[expectLength++]=HANGUL_K_KIYEOK_SIOS;
936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_normalize(input, inLength,
939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UNORM_FCD, 0,
940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           output, sizeof(output)/U_SIZEOF_UCHAR,
941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           &errorCode);
942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_normalize(long input, UNORM_FCD) failed with %s - (Are you missing data?)\n", u_errorName(errorCode));
944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if(length!=expectLength || u_memcmp(output, expect, length)!=0) {
945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_normalize(long input, UNORM_FCD) produced wrong result\n");
946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<length; ++i) {
947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(output[i]!=expect[i]) {
948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                log_err("    FCD[%d]==U+%04lx expected U+%04lx\n", i, output[i], expect[i]);
949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* API test for unorm_concatenate() - for real test strings see intltest/tstnorm.cpp */
956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestConcatenate(void) {
958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* "re + 'sume'" */
959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar
960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    left[]={
961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x72, 0x65, 0
962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    right[]={
964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x301, 0x73, 0x75, 0x6d, 0xe9, 0
965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    expect[]={
967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x72, 0xe9, 0x73, 0x75, 0x6d, 0xe9, 0
968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar buffer[100];
971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length;
973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* left with length, right NUL-terminated */
975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(left, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode);
977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode) || length!=6 || 0!=u_memcmp(buffer, expect, length)) {
978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: unorm_concatenate()=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* preflighting */
982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(left, 2, right, -1, NULL, 0, UNORM_NFC, 0, &errorCode);
984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=6) {
985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: unorm_concatenate(preflighting)=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[2]=0x5555;
989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(left, 2, right, -1, buffer, 1, UNORM_NFC, 0, &errorCode);
991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=6 || buffer[2]!=0x5555) {
992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: unorm_concatenate(preflighting 2)=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* enter with U_FAILURE */
996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[2]=0xaaaa;
997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_UNEXPECTED_TOKEN;
998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(left, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode);
999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_UNEXPECTED_TOKEN || buffer[2]!=0xaaaa) {
1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error: unorm_concatenate(failure)=%ld failed with %s\n", length, u_errorName(errorCode));
1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* illegal arguments */
1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[2]=0xaaaa;
1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(NULL, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode);
1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || buffer[2]!=0xaaaa) {
1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: unorm_concatenate(left=NULL)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_concatenate(left, 2, right, -1, NULL, 100, UNORM_NFC, 0, &errorCode);
1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error: unorm_concatenate(buffer=NULL)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode));
1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)enum {
1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _PLUS=0x2b
1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char *const _modeString[UNORM_MODE_COUNT]={
1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    "0", "NONE", "NFD", "NFKD", "NFC", "NFKC", "FCD"
1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_testIter(const UChar *src, int32_t srcLength,
1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          UCharIterator *iter, UNormalizationMode mode, UBool forward,
1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          const UChar *out, int32_t outLength,
1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          const int32_t *srcIndexes, int32_t srcIndexesLength) {
1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar buffer[4];
1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UChar *expect, *outLimit, *in;
1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length, i, expectLength, expectIndex, prevIndex, index, inLength;
1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool neededToNormalize, expectNeeded;
1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    outLimit=out+outLength;
1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(forward) {
1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect=out;
1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        i=index=0;
1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expect=outLimit;
1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        i=srcIndexesLength-2;
1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        index=srcLength;
1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;;) {
1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        prevIndex=index;
1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(forward) {
1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(!iter->hasNext(iter)) {
1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return;
1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            length=unorm_next(iter,
1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              mode, 0,
1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              (UBool)(out!=NULL), &neededToNormalize,
1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              &errorCode);
1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            expectIndex=srcIndexes[i+1];
1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            in=src+prevIndex;
1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            inLength=expectIndex-prevIndex;
1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(out!=NULL) {
1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* get output piece from between plus signs */
1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectLength=0;
1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while((expect+expectLength)!=outLimit && expect[expectLength]!=_PLUS) {
1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++expectLength;
1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectNeeded=(UBool)(0!=u_memcmp(buffer, in, inLength));
1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expect=in;
1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectLength=inLength;
1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectNeeded=FALSE;
1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(!iter->hasPrevious(iter)) {
1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return;
1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            length=unorm_previous(iter,
1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  mode, 0,
1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  (UBool)(out!=NULL), &neededToNormalize,
1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  &errorCode);
1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            expectIndex=srcIndexes[i];
1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            in=src+expectIndex;
1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            inLength=prevIndex-expectIndex;
1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(out!=NULL) {
1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* get output piece from between plus signs */
1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectLength=0;
1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while(expect!=out && expect[-1]!=_PLUS) {
1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++expectLength;
1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    --expect;
1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectNeeded=(UBool)(0!=u_memcmp(buffer, in, inLength));
1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expect=in;
1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectLength=inLength;
1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expectNeeded=FALSE;
1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        index=iter->getIndex(iter, UITER_CURRENT);
1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(errorCode)) {
1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("error unorm iteration (next/previous %d %s)[%d]: %s - (Are you missing data?)\n",
1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    forward, _modeString[mode], i, u_errorName(errorCode));
1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(expectIndex!=index) {
1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_err("error unorm iteration (next/previous %d %s): index[%d] wrong, got %d expected %d\n",
1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    forward, _modeString[mode], i, index, expectIndex);
1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(expectLength!=length) {
1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_err("error unorm iteration (next/previous %d %s): length[%d] wrong, got %d expected %d\n",
1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    forward, _modeString[mode], i, length, expectLength);
1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(0!=u_memcmp(expect, buffer, length)) {
1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_err("error unorm iteration (next/previous %d %s): output string[%d] wrong\n",
1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    forward, _modeString[mode], i);
1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(neededToNormalize!=expectNeeded) {
1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(forward) {
1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            expect+=expectLength+1; /* go after the + */
1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++i;
1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            --expect; /* go before the + */
1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            --i;
1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestNextPrevious() {
1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar
1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    src[]={ /* input string */
1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0xa0, 0xe4, 0x63, 0x302, 0x327, 0xac00, 0x3133
1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfd[]={ /* + separates expected output pieces */
1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0xa0, _PLUS, 0x61, 0x308, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0x1100, 0x1161, _PLUS, 0x3133
1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfkd[]={
1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x20, _PLUS, 0x61, 0x308, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0x1100, 0x1161, _PLUS, 0x11aa
1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfc[]={
1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0xa0, _PLUS, 0xe4, _PLUS, 0xe7, 0x302, _PLUS, 0xac00, _PLUS, 0x3133
1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfkc[]={
1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x20, _PLUS, 0xe4, _PLUS, 0xe7, 0x302, _PLUS, 0xac03
1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fcd[]={
1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0xa0, _PLUS, 0xe4, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0xac00, _PLUS, 0x3133
1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* expected iterator indexes in the source string for each iteration piece */
1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const int32_t
1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfdIndexes[]={
1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0, 1, 2, 5, 6, 7
1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfkdIndexes[]={
1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0, 1, 2, 5, 6, 7
1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfcIndexes[]={
1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0, 1, 2, 5, 6, 7
1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nfkcIndexes[]={
1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0, 1, 2, 5, 7
1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    },
1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fcdIndexes[]={
1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0, 1, 2, 5, 6, 7
1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UCharIterator iter;
1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar buffer[4];
1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length;
1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool neededToNormalize;
1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uiter_setString(&iter, src, sizeof(src)/U_SIZEOF_UCHAR);
1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test iteration with doNormalize */
1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, TRUE, nfd, sizeof(nfd)/U_SIZEOF_UCHAR, nfdIndexes, sizeof(nfdIndexes)/4);
1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, TRUE, nfkd, sizeof(nfkd)/U_SIZEOF_UCHAR, nfkdIndexes, sizeof(nfkdIndexes)/4);
1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, TRUE, nfc, sizeof(nfc)/U_SIZEOF_UCHAR, nfcIndexes, sizeof(nfcIndexes)/4);
1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, TRUE, nfkc, sizeof(nfkc)/U_SIZEOF_UCHAR, nfkcIndexes, sizeof(nfkcIndexes)/4);
1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, TRUE, fcd, sizeof(fcd)/U_SIZEOF_UCHAR, fcdIndexes, sizeof(fcdIndexes)/4);
1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, FALSE, nfd, sizeof(nfd)/U_SIZEOF_UCHAR, nfdIndexes, sizeof(nfdIndexes)/4);
1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, FALSE, nfkd, sizeof(nfkd)/U_SIZEOF_UCHAR, nfkdIndexes, sizeof(nfkdIndexes)/4);
1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, FALSE, nfc, sizeof(nfc)/U_SIZEOF_UCHAR, nfcIndexes, sizeof(nfcIndexes)/4);
1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, FALSE, nfkc, sizeof(nfkc)/U_SIZEOF_UCHAR, nfkcIndexes, sizeof(nfkcIndexes)/4);
1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, FALSE, fcd, sizeof(fcd)/U_SIZEOF_UCHAR, fcdIndexes, sizeof(fcdIndexes)/4);
1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test iteration without doNormalize */
1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, TRUE, NULL, 0, nfdIndexes, sizeof(nfdIndexes)/4);
1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, TRUE, NULL, 0, nfkdIndexes, sizeof(nfkdIndexes)/4);
1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, TRUE, NULL, 0, nfcIndexes, sizeof(nfcIndexes)/4);
1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, TRUE, NULL, 0, nfkcIndexes, sizeof(nfkcIndexes)/4);
1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=0;
1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, TRUE, NULL, 0, fcdIndexes, sizeof(fcdIndexes)/4);
1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, FALSE, NULL, 0, nfdIndexes, sizeof(nfdIndexes)/4);
1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, FALSE, NULL, 0, nfkdIndexes, sizeof(nfkdIndexes)/4);
1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, FALSE, NULL, 0, nfcIndexes, sizeof(nfcIndexes)/4);
1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, FALSE, NULL, 0, nfkcIndexes, sizeof(nfkcIndexes)/4);
1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=iter.length;
1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, FALSE, NULL, 0, fcdIndexes, sizeof(fcdIndexes)/4);
1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* try without neededToNormalize */
1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[0]=5;
1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      UNORM_NFD, 0, TRUE, NULL,
1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode) || length!=2 || buffer[0]!=nfd[2] || buffer[1]!=nfd[3]) {
1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("error unorm_next(without needed) %s - (Are you missing data?)\n", u_errorName(errorCode));
1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* preflight */
1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    neededToNormalize=9;
1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(&iter, NULL, 0,
1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      UNORM_NFD, 0, TRUE, &neededToNormalize,
1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || neededToNormalize!=FALSE || length!=2) {
1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_next(pure preflighting) %s\n", u_errorName(errorCode));
1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[0]=buffer[1]=5;
1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    neededToNormalize=9;
1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(&iter, buffer, 1,
1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      UNORM_NFD, 0, TRUE, &neededToNormalize,
1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || neededToNormalize!=FALSE || length!=2 || buffer[1]!=5) {
1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_next(preflighting) %s\n", u_errorName(errorCode));
1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* no iterator */
1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[0]=buffer[1]=5;
1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    neededToNormalize=9;
1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(NULL, buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      UNORM_NFD, 0, TRUE, &neededToNormalize,
1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_next(no iterator) %s\n", u_errorName(errorCode));
1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* illegal mode */
1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[0]=buffer[1]=5;
1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    neededToNormalize=9;
1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      (UNormalizationMode)0, 0, TRUE, &neededToNormalize,
1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_next(illegal mode) %s\n", u_errorName(errorCode));
1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* error coming in */
1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_MISPLACED_QUANTIFIER;
1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buffer[0]=5;
1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iter.index=1;
1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      UNORM_NFD, 0, TRUE, NULL,
1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      &errorCode);
1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_MISPLACED_QUANTIFIER) {
1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("error unorm_next(U_MISPLACED_QUANTIFIER) %s\n", u_errorName(errorCode));
1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestFCNFKCClosure(void) {
1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const struct {
1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar32 c;
1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const UChar s[6];
1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } tests[]={
1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x00C4, { 0 } },
1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x00E4, { 0 } },
1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x037A, { 0x0020, 0x03B9, 0 } },
1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x03D2, { 0x03C5, 0 } },
1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x20A8, { 0x0072, 0x0073, 0 } },
1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x210B, { 0x0068, 0 } },
1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x210C, { 0x0068, 0 } },
1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x2121, { 0x0074, 0x0065, 0x006C, 0 } },
1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x2122, { 0x0074, 0x006D, 0 } },
1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x2128, { 0x007A, 0 } },
1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x1D5DB, { 0x0068, 0 } },
1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x1D5ED, { 0x007A, 0 } },
1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { 0x0061, { 0 } }
1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar buffer[8];
1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i, length;
1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<LENGTHOF(tests); ++i) {
1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCode=U_ZERO_ERROR;
1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=u_getFC_NFKC_Closure(tests[i].c, buffer, LENGTHOF(buffer), &errorCode);
1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(errorCode) || length!=u_strlen(buffer) || 0!=u_strcmp(tests[i].s, buffer)) {
1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("u_getFC_NFKC_Closure(U+%04lx) is wrong (%s) - (Are you missing data?)\n", tests[i].c, u_errorName(errorCode));
1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* error handling */
1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=u_getFC_NFKC_Closure(0x5c, NULL, LENGTHOF(buffer), &errorCode);
1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("u_getFC_NFKC_Closure(dest=NULL) is wrong (%s)\n", u_errorName(errorCode));
1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=u_getFC_NFKC_Closure(0x5c, buffer, LENGTHOF(buffer), &errorCode);
1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("u_getFC_NFKC_Closure(U_FAILURE) is wrong (%s)\n", u_errorName(errorCode));
1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestQuickCheckPerCP() {
1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar32 c, lead, trail;
1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar s[U16_MAX_LENGTH], nfd[16];
1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length, lccc1, lccc2, tccc1, tccc2;
1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t qc1, qc2;
1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(
1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_NFD_QUICK_CHECK)!=(int32_t)UNORM_YES ||
1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_NFKD_QUICK_CHECK)!=(int32_t)UNORM_YES ||
1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_NFC_QUICK_CHECK)!=(int32_t)UNORM_MAYBE ||
1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_NFKC_QUICK_CHECK)!=(int32_t)UNORM_MAYBE ||
1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_LEAD_CANONICAL_COMBINING_CLASS)!=u_getIntPropertyMaxValue(UCHAR_CANONICAL_COMBINING_CLASS) ||
1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_getIntPropertyMaxValue(UCHAR_TRAIL_CANONICAL_COMBINING_CLASS)!=u_getIntPropertyMaxValue(UCHAR_CANONICAL_COMBINING_CLASS)
1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ) {
1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("wrong result from one of the u_getIntPropertyMaxValue(UCHAR_NF*_QUICK_CHECK) or UCHAR_*_CANONICAL_COMBINING_CLASS\n");
1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*
1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * compare the quick check property values for some code points
1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * to the quick check results for checking same-code point strings
1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    c=0;
1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(c<0x110000) {
1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=0;
1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        U16_APPEND_UNSAFE(s, length, c);
1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc1=u_getIntPropertyValue(c, UCHAR_NFC_QUICK_CHECK);
1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc2=unorm_quickCheck(s, length, UNORM_NFC, &errorCode);
1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(qc1!=qc2) {
1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("u_getIntPropertyValue(NFC)=%d != %d=unorm_quickCheck(NFC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c);
1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc1=u_getIntPropertyValue(c, UCHAR_NFD_QUICK_CHECK);
1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc2=unorm_quickCheck(s, length, UNORM_NFD, &errorCode);
1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(qc1!=qc2) {
1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("u_getIntPropertyValue(NFD)=%d != %d=unorm_quickCheck(NFD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c);
1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc1=u_getIntPropertyValue(c, UCHAR_NFKC_QUICK_CHECK);
1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc2=unorm_quickCheck(s, length, UNORM_NFKC, &errorCode);
1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(qc1!=qc2) {
1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("u_getIntPropertyValue(NFKC)=%d != %d=unorm_quickCheck(NFKC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c);
1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc1=u_getIntPropertyValue(c, UCHAR_NFKD_QUICK_CHECK);
1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        qc2=unorm_quickCheck(s, length, UNORM_NFKD, &errorCode);
1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(qc1!=qc2) {
1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("u_getIntPropertyValue(NFKD)=%d != %d=unorm_quickCheck(NFKD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c);
1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=unorm_normalize(s, length, UNORM_NFD, 0, nfd, LENGTHOF(nfd), &errorCode);
1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* length-length == 0 is used to get around a compiler warning. */
1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        U16_GET(nfd, 0, length-length, length, lead);
1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        U16_GET(nfd, 0, length-1, length, trail);
1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lccc1=u_getIntPropertyValue(c, UCHAR_LEAD_CANONICAL_COMBINING_CLASS);
1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lccc2=u_getCombiningClass(lead);
1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tccc1=u_getIntPropertyValue(c, UCHAR_TRAIL_CANONICAL_COMBINING_CLASS);
1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tccc2=u_getCombiningClass(trail);
1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(lccc1!=lccc2) {
1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_err("u_getIntPropertyValue(lccc)=%d != %d=u_getCombiningClass(lead) for U+%04x\n",
1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    lccc1, lccc2, c);
1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(tccc1!=tccc2) {
1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_err("u_getIntPropertyValue(tccc)=%d != %d=u_getCombiningClass(trail) for U+%04x\n",
1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    tccc1, tccc2, c);
1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* skip some code points */
1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        c=(20*c)/19+1;
1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestComposition(void) {
1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const struct {
1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UNormalizationMode mode;
1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uint32_t options;
1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar input[12];
1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar expect[12];
1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } cases[]={
1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*
1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * special cases for UAX #15 bug
1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * see Unicode Corrigendum #5: Normalization Idempotency
1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * at http://unicode.org/versions/corrigendum5.html
1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * (was Public Review Issue #29)
1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         */
1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327 },         { 0x1100, 0x0300, 0x1161, 0x0327 } },
1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 }, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 } },
1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { UNORM_NFC, 0, { 0xac00, 0x0300, 0x0327, 0x11a8 },         { 0xac00, 0x0327, 0x0300, 0x11a8 } },
1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        { UNORM_NFC, 0, { 0x0b47, 0x0300, 0x0b3e },                 { 0x0b47, 0x0300, 0x0b3e } },
1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* TODO: add test cases for UNORM_FCC here (j2151) */
1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar output[16];
1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode;
1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i, length;
1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<LENGTHOF(cases); ++i) {
1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCode=U_ZERO_ERROR;
1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=unorm_normalize(
1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    cases[i].input, -1,
1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    cases[i].mode, cases[i].options,
1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    output, LENGTHOF(output),
1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    &errorCode);
1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( U_FAILURE(errorCode) ||
1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            length!=u_strlen(cases[i].expect) ||
1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            0!=u_memcmp(output, cases[i].expect, length)
1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ) {
1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_data_err("unexpected result for case %d - (Are you missing data?)\n", i);
1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TestGetDecomposition() {
1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar decomp[32];
1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length;
1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode=U_ZERO_ERROR;
1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UNormalizer2 *n2=unorm2_getInstance(NULL, "nfc", UNORM2_COMPOSE_CONTIGUOUS, &errorCode);
1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err_status(errorCode, "unorm2_getInstance(nfc/FCC) failed: %s\n", u_errorName(errorCode));
1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0x20, decomp, LENGTHOF(decomp), &errorCode);
1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode) || length>=0) {
1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(space) failed\n");
1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0xe4, decomp, LENGTHOF(decomp), &errorCode);
1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode) || length!=2 || decomp[0]!=0x61 || decomp[1]!=0x308 || decomp[2]!=0) {
1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(a-umlaut) failed\n");
1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0xac01, decomp, LENGTHOF(decomp), &errorCode);
1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode) || length!=3 || decomp[0]!=0x1100 || decomp[1]!=0x1161 || decomp[2]!=0x11a8 || decomp[3]!=0) {
1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(Hangul syllable U+AC01) failed\n");
1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0xac01, NULL, 0, &errorCode);
1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3) {
1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(Hangul syllable U+AC01) overflow failed\n");
1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0xac01, decomp, -1, &errorCode);
1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(capacity<0) failed\n");
1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode=U_ZERO_ERROR;
1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=unorm2_getDecomposition(n2, 0xac01, NULL, 4, &errorCode);
1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("unorm2_getDecomposition(decomposition=NULL) failed\n");
1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_NORMALIZATION */
1515