1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * COPYRIGHT:
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Copyright (C) 2001-2011 IBM, Inc.   All Rights Reserved.
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ********************************************************************/
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************************
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File dumpce.cpp
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Name          Date           Description
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* synwee        May 31 2001    Creation
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*********************************************************************************
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* This program outputs the collation elements used for a requested tailoring.
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Usage:
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*     dumpce options... please check main function.
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/utypes.h>
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/ucol.h>
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/uloc.h>
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/ucoleitr.h>
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/uchar.h>
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/uscript.h>
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/utf16.h>
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/putil.h>
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/ustring.h>
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <time.h>
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucol_tok.h"
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uoptions.h"
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucol_imp.h"
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/ures.h>
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/uniset.h>
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/usetiter.h>
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Command line option variables.
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* These global variables are set according to the options specified on the
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* command line by the user.
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UOption options[]={
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 00 */ UOPTION_HELP_H,
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 01 */ UOPTION_HELP_QUESTION_MARK,
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 02 */ {"locale",        NULL, NULL, NULL, 'l', UOPT_REQUIRES_ARG, 0},
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 03 */ {"serialize",     NULL, NULL, NULL, 'z', UOPT_NO_ARG, 0},
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	/* 04 */ UOPTION_DESTDIR,
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 05 */ UOPTION_SOURCEDIR,
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 06 */ {"attribute",     NULL, NULL, NULL, 'a', UOPT_REQUIRES_ARG, 0},
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 07 */ {"rule",          NULL, NULL, NULL, 'r', UOPT_REQUIRES_ARG, 0},
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 08 */ {"normalization", NULL, NULL, NULL, 'n', UOPT_REQUIRES_ARG, 0},
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 09 */ {"scripts",       NULL, NULL, NULL, 't', UOPT_NO_ARG, 0},
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 10 */ {"reducehan",     NULL, NULL, NULL, 'e', UOPT_NO_ARG, 0},
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	/* 11 */ UOPTION_VERBOSE,
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* 12 */ {"wholescripts",      NULL, NULL, NULL, 'W', UOPT_NO_ARG, 0}
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Collator used in this program
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UCollator *COLLATOR_;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Output strea, used in this program
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic FILE *OUTPUT_;
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UColAttributeValue ATTRIBUTE_[UCOL_ATTRIBUTE_COUNT] = {
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCOL_DEFAULT, UCOL_DEFAULT, UCOL_DEFAULT, UCOL_DEFAULT, UCOL_DEFAULT,
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCOL_DEFAULT, UCOL_DEFAULT, UCOL_DEFAULT,
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct {
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int   value;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char *name;
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} EnumNameValuePair;
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const EnumNameValuePair ATTRIBUTE_NAME_[] = {
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_FRENCH_COLLATION, "UCOL_FRENCH_COLLATION"},
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_ALTERNATE_HANDLING, "UCOL_ALTERNATE_HANDLING"},
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_CASE_FIRST, "UCOL_CASE_FIRST"},
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_CASE_LEVEL, "UCOL_CASE_LEVEL"},
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_NORMALIZATION_MODE,
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "UCOL_NORMALIZATION_MODE|UCOL_DECOMPOSITION_MODE"},
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_STRENGTH, "UCOL_STRENGTH"},
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	{UCOL_HIRAGANA_QUATERNARY_MODE, "UCOL_HIRAGANA_QUATERNARY_MODE"},
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_NUMERIC_COLLATION, "UCOL_NUMERIC_COLLATION"},
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const EnumNameValuePair ATTRIBUTE_VALUE_[] = {
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_PRIMARY, "UCOL_PRIMARY"},
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_SECONDARY, "UCOL_SECONDARY"},
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_TERTIARY, "UCOL_TERTIARY|UCOL_DEFAULT_STRENGTH"},
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_QUATERNARY, "UCOL_QUATERNARY"},
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_IDENTICAL, "UCOL_IDENTICAL"},
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_OFF, "UCOL_OFF"},
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_ON, "UCOL_ON"},
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_SHIFTED, "UCOL_SHIFTED"},
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_NON_IGNORABLE, "UCOL_NON_IGNORABLE"},
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_LOWER_FIRST, "UCOL_LOWER_FIRST"},
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {UCOL_UPPER_FIRST, "UCOL_UPPER_FIRST"},
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct {
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar ch[32];
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int   count; // number of codepoint
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool tailored;
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} ScriptElement;
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Writes the hexadecimal of a null-terminated array of codepoints into a
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param f UFILE instance to store
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param c codepoints array
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize(FILE *f, const UChar *c)
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar cp = *(c ++);
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(f, " %04x", cp);
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (*c != 0) {
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cp = *(c ++);
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, " %04x", cp);
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Writes the hexadecimal of a non-null-terminated array of codepoints into a
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param f UFILE instance to store
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param c codepoints array
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param l codepoints array length
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize(FILE *f, const UChar *c, int l)
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int   count = 1;
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar cp    = *(c ++);
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(f, " %04x", cp);
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (count < l) {
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cp = *(c ++);
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, " %04x", cp);
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count ++;
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Sets the iterator to the argument string and outputs the collation elements.
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param f file output stream
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param iter collation element iterator
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize(FILE *f, UCollationElements *iter) {
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   *codepoint = iter->iteratordata_.string;
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // unlikely that sortkeys will be over this size
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t  sortkey[64];
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t *psortkey = sortkey;
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int      sortkeylength = 0;
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (iter->iteratordata_.flags & UCOL_ITER_HASLEN) {
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize(f, codepoint, iter->iteratordata_.endp - codepoint);
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sortkeylength = ucol_getSortKey(iter->iteratordata_.coll, codepoint,
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        iter->iteratordata_.endp - codepoint, sortkey, 64);
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize(f, codepoint);
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sortkeylength = ucol_getSortKey(iter->iteratordata_.coll, codepoint,
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        -1, sortkey, 64);
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[11].doesOccur) {
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize(stdout, codepoint);
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "\n");
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(f, "; ");
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t ce = ucol_next(iter, &error);
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, "Error retrieving collation elements\n");
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (TRUE) {
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, "[");
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (UCOL_PRIMARYORDER(ce) != 0) {
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(f, "%04x", UCOL_PRIMARYORDER(ce));
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, ",");
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (UCOL_SECONDARYORDER(ce) != 0) {
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(f, " %02x", UCOL_SECONDARYORDER(ce));
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, ",");
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (UCOL_TERTIARYORDER(ce) != 0) {
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(f, " %02x", UCOL_TERTIARYORDER(ce));
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, "] ");
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ce = ucol_next(iter, &error);
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ce == UCOL_NULLORDER) {
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error retrieving collation elements");
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (sortkeylength > 64) {
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, "Sortkey exceeds pre-allocated size");
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(f, "[");
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (TRUE) {
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, "%02x", *psortkey);
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        psortkey ++;
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((*psortkey) == 0) {
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(f, " ");
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(f, "]\n");
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Serializes the contraction within the given argument rule
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param f file output stream
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param r rule
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param rlen rule length
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param contractionsonly flag to indicate if only contractions are to be
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                         output or all collation elements
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param iter iterator to iterate over collation elements
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize(FILE *f, UChar *rule, int rlen, UBool contractiononly,
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               UCollationElements *iter) {
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar           *current  = NULL;
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         strength = 0;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chOffset = 0;
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chLen    = 0;
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exOffset = 0;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exLen    = 0;
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixOffset = 0;
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixLen    = 0;
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint8_t          specs    = 0;
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UBool            rstart   = TRUE;
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColTokenParser  src;
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColOptionSet    opts;
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UParseError      parseError;
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UErrorCode       error    = U_ZERO_ERROR;
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.opts = &opts;
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.source       = rule;
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	src.current = rule;
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.end          = rule + rlen;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraCurrent = src.end;
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraEnd     = src.end + UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while ((current = ucol_tok_parseNextToken(&src, rstart, &parseError,
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &error)) != NULL) {
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      chOffset = src.parsedToken.charsOffset;
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      chLen = src.parsedToken.charsLen;
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // contractions handled here
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!contractiononly || chLen > 1) {
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, rule + chOffset, chLen, &error);
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Error setting text in iterator\n");
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            serialize(f, iter);
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rstart = FALSE;
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the attribute values in the argument collator into the output stream
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param collator
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputAttribute(UCollator *collator, UErrorCode *error)
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UColAttribute attribute = UCOL_FRENCH_COLLATION;
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (attribute < UCOL_ATTRIBUTE_COUNT) {
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int count = 0;
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (TRUE) {
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // getting attribute name
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ATTRIBUTE_NAME_[count].value == attribute) {
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "%s = ", ATTRIBUTE_NAME_[count].name);
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count ++;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count = 0;
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int attributeval = ucol_getAttribute(collator, attribute, error);
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(*error)) {
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Failure in reading collator attribute\n");
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (TRUE) {
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // getting attribute value
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ATTRIBUTE_VALUE_[count].value == attributeval) {
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "%s\n", ATTRIBUTE_VALUE_[count].name);
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count ++;
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        attribute = (UColAttribute)(attribute + 1);
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the normalization mode in the argument collator into the output stream
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param collator
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputNormalization(UCollator *collator)
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	UErrorCode status = U_ZERO_ERROR;
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int normmode = ucol_getAttribute(collator, UCOL_NORMALIZATION_MODE, &status);
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int count = 0;
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (TRUE) {
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // getting attribute name
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ATTRIBUTE_VALUE_[count].value == normmode) {
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count ++;
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "NORMALIZATION MODE = %s\n",
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ATTRIBUTE_VALUE_[count].name);
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Output the collation element belonging to the locale into a file
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param locale string
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param fullrules flag to indicate if only tailored collation elements are to
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*        be output or all collation elements
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize(const char *locale, UBool tailoredonly) {
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode  error              = U_ZERO_ERROR;
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar       str[128];
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int         strlen = 0;
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "# This file contains the serialized collation elements\n");
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "# as of the collation version indicated below.\n");
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "# Data format: xxxx xxxx..; [yyyy, yy, yy] [yyyy, yy, yy] ... [yyyy, yy, yy] [zz zz..\n");
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "#              where xxxx are codepoints in hexadecimals,\n");
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "#              yyyyyyyy are the corresponding\n");
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "#              collation elements in hexadecimals\n");
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "#              and zz are the sortkey values in hexadecimals\n");
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "\n# Collator information\n");
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "\nLocale: %s\n", locale);
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stdout, "Locale: %s\n", locale);
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UVersionInfo version;
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_getVersion(COLLATOR_, version);
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "Version number: %d.%d.%d.%d\n",
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      version[0], version[1], version[2], version[3]);
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputAttribute(COLLATOR_, &error);
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputNormalization(COLLATOR_);
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollationElements *iter = ucol_openElements(COLLATOR_, str, strlen,
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                 &error);
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error creating iterator\n");
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!tailoredonly) {
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "\n# Range of unicode characters\n\n");
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32     codepoint          = 0;
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (codepoint <= UCHAR_MAX_VALUE) {
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (u_isdefined(codepoint)) {
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strlen = 0;
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UTF16_APPEND_CHAR_UNSAFE(str, strlen, codepoint);
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                str[strlen] = 0;
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setText(iter, str, strlen, &error);
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (U_FAILURE(error)) {
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "Error setting text in iterator\n");
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return;
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                serialize(OUTPUT_, iter);
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            codepoint ++;
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar    ucarules[0x10000];
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   *rules;
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t  rulelength = 0;
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    rules      = ucarules;
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (tailoredonly) {
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t  rulelength = 0;
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const UChar   *temp = ucol_getRules(COLLATOR_, &rulelength);
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE > 0x10000) {
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rules = (UChar *)malloc(sizeof(UChar) *
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE));
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        memcpy(rules, temp, rulelength * sizeof(UChar));
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rules[rulelength] = 0;
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "\n# Tailorings\n\n");
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize(OUTPUT_, rules, rulelength, FALSE, iter);
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (rules != ucarules) {
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            free(rules);
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rulelength = ucol_getRulesEx(COLLATOR_, UCOL_FULL_RULES, ucarules,
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                     0x10000);
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE > 0x10000) {
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rules = (UChar *)malloc(sizeof(UChar) *
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE));
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rulelength = ucol_getRulesEx(COLLATOR_, UCOL_FULL_RULES, rules,
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                         rulelength);
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "\n# Contractions\n\n");
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize(OUTPUT_, rules, rulelength, TRUE, iter);
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (rules != ucarules) {
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            free(rules);
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_closeElements(iter);
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Sets the collator with the attribute values
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param collator
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param error status
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid setAttributes(UCollator *collator, UErrorCode *error)
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int count = 0;
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (count < UCOL_ATTRIBUTE_COUNT) {
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ATTRIBUTE_[count] != UCOL_DEFAULT) {
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(collator, (UColAttribute)count,
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              ATTRIBUTE_[count], error);
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(*error)) {
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count ++;
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Appends directory path with an ending seperator if necessary.
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param path with enough space to append one seperator
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return new directory path length
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint appendDirSeparator(char *dir)
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int dirlength = strlen(dir);
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char dirending = dir[dirlength - 1];
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (dirending != U_FILE_SEP_CHAR) {
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dir[dirlength] = U_FILE_SEP_CHAR;
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dir[dirlength + 1] = 0;
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return dirlength + 1;
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return dirlength;
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Output the collation element into a file
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serialize() {
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char filename[128];
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int  dirlength = 0;
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[4].doesOccur) {
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strcpy(filename, options[4].value);
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dirlength = appendDirSeparator(filename);
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[2].doesOccur) {
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const char    *locale      = (char *)options[2].value;
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t  localeindex = 0;
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (strcmp(locale, "all") == 0) {
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (options[4].doesOccur) {
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strcat(filename, "UCA.txt");
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                OUTPUT_ = fopen(filename, "w");
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (OUTPUT_ == NULL) {
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "Cannot open file:%s\n", filename);
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return;
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "UCA\n");
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UErrorCode error = U_ZERO_ERROR;
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            COLLATOR_ = ucol_open("en_US", &error);
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Collator creation failed:");
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, u_errorName(error));
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto CLOSEUCA;
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            setAttributes(COLLATOR_, &error);
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Collator attribute setting failed:");
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, u_errorName(error));
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto CLOSEUCA;
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            serialize("UCA", FALSE);
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCLOSEUCA :
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (options[4].doesOccur) {
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                filename[dirlength] = 0;
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fclose(OUTPUT_);
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_close(COLLATOR_);
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            localeindex = ucol_countAvailable() - 1;
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Number of locales: %d\n", localeindex + 1);
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            locale      = ucol_getAvailable(localeindex);
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (TRUE) {
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UErrorCode error = U_ZERO_ERROR;
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            COLLATOR_ = ucol_open(locale, &error);
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Collator creation failed:");
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, u_errorName(error));
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto CLOSETAILOR;
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            setAttributes(COLLATOR_, &error);
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Collator attribute setting failed:");
539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, u_errorName(error));
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto CLOSETAILOR;
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (options[4].doesOccur) {
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strcat(filename, locale);
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strcat(filename, ".txt");
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                OUTPUT_ = fopen(filename, "w");
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (OUTPUT_ == NULL) {
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "Cannot open file:%s\n", filename);
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return;
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (options[3].doesOccur) {
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                serialize(locale, TRUE);
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_close(COLLATOR_);
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCLOSETAILOR :
561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (options[4].doesOccur) {
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                filename[dirlength] = 0;
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fclose(OUTPUT_);
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            localeindex --;
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (localeindex < 0) {
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            locale = ucol_getAvailable(localeindex);
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[7].doesOccur) {
575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        char inputfilename[128] = "";
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // rules are to be used
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[5].doesOccur) {
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strcpy(inputfilename, options[5].value);
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendDirSeparator(inputfilename);
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strcat(inputfilename, options[7].value);
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        FILE *input = fopen(inputfilename, "r");
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (input == NULL) {
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Cannot open file:%s\n", filename);
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        char   s[1024];
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar  rule[1024];
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar *prule = rule;
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int    size = 1024;
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // synwee TODO: make this part dynamic
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (fscanf(input, "%[^\n]s", s) != EOF) {
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            size -= u_unescape(s, prule, size);
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            prule = prule + u_strlen(prule);
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fclose(input);
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[4].doesOccur) {
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strcat(filename, "Rules.txt");
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            OUTPUT_ = fopen(filename, "w");
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (OUTPUT_ == NULL) {
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Cannot open file:%s\n", filename);
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Rules\n");
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode  error = U_ZERO_ERROR;
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UParseError parseError;
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        COLLATOR_ = ucol_openRules(rule, u_strlen(rule), UCOL_DEFAULT,
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UCOL_DEFAULT_STRENGTH, &parseError, &error);
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Collator creation failed:");
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, u_errorName(error));
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            goto CLOSERULES;
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        setAttributes(COLLATOR_, &error);
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Collator attribute setting failed:");
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, u_errorName(error));
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            goto CLOSERULES;
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize("Rule-based", TRUE);
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_close(COLLATOR_);
629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCLOSERULES :
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[4].doesOccur) {
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            filename[dirlength] = 0;
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fclose(OUTPUT_);
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Parse for enum values.
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Note this only works for positive enum values.
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param enumarray array containing names of the enum values in string and
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*        their corresponding value.
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*        declared enum value.
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param str string to be parsed
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return corresponding integer enum value or -1 if value is not found.
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint parseEnums(const EnumNameValuePair enumarray[], const char *str)
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *enumname = enumarray[0].name;
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int result = atoi(str);
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (result == 0 && str[0] != '0') {
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (strcmp(enumname, str) != 0) {
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // checking for multiple enum names sharing the same values
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            enumname = strstr(enumname, str);
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (enumname != NULL) {
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                int size = strchr(enumname, '|') - enumname;
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (size < 0) {
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    size = strlen(enumname);
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (size == (int)strlen(str)) {
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return enumarray[result].value;
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            result ++;
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (&(enumarray[result]) == NULL) {
666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return -1;
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            enumname = enumarray[result].name;
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return -1;
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Parser for attribute name value pair
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid parseAttributes() {
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char str[32];
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *pname = options[6].value;
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *pend  = options[6].value + strlen(options[6].value);
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *pvalue;
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (pname < pend) {
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        pvalue = strchr(pname, '=');
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (pvalue == NULL) {
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout,
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    "No matching value found for attribute argument %s\n",
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pname);
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int count = pvalue - pname;
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strncpy(str, pname, count);
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        str[count] = 0;
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int name = parseEnums(ATTRIBUTE_NAME_, str);
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (name == -1) {
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Attribute name not found: %s\n", str);
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        pvalue ++;
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // getting corresponding enum value
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        pname = strchr(pvalue, ',');
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (pname == NULL) {
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pname = pend;
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count = pname - pvalue;
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strncpy(str, pvalue, count);
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        str[count] = 0;
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int value = parseEnums(ATTRIBUTE_VALUE_, str);
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (value == -1) {
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Attribute value not found: %s\n", str);
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ATTRIBUTE_[name] = (UColAttributeValue)value;
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        pname ++;
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Checks if the locale argument is a base language
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param locale to be checked
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return TRUE if it is a base language
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline UBool checkLocaleForLanguage(const char *locale)
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return strlen(locale) <= 2;
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Converts a UChar array into its string form "xxxx xxxx"
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param ch array of UChar characters
733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param count number of UChar characters
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputUChar(UChar ch[], int count)
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int i = 0; i < count; i ++) {
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "%04X ", ch[i]);
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* If it is a primary difference returns -1 or 1.
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* If it is a secondary difference returns -2 or 2.
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* If it is a tertiary difference returns -3 or 3.
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* If equals returns 0.
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint compareSortKey(const void *elem1, const void *elem2)
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // compare the 2 script element sort key
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar     *ch1   = ((ScriptElement *)elem1)->ch;
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar     *ch2   = ((ScriptElement *)elem2)->ch;
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int        size1 = ((ScriptElement *)elem1)->count;
754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int        size2 = ((ScriptElement *)elem2)->count;
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_setStrength(COLLATOR_, UCOL_PRIMARY);
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int result = ucol_strcoll(COLLATOR_, ch1, size1, ch2, size2);
759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (result == 0) {
760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_setStrength(COLLATOR_, UCOL_SECONDARY);
761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        result = ucol_strcoll(COLLATOR_, ch1, size1, ch2, size2);
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (result == 0) {
763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setStrength(COLLATOR_, UCOL_TERTIARY);
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            result = ucol_strcoll(COLLATOR_, ch1, size1, ch2, size2);
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (result < 0) {
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return -3;
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (result > 0) {
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return 3;
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (result < 0) {
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return -2;
774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (result > 0) {
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return 2;
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Output serialized script elements
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param element the element to output
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param compare the comparison with the previous element
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param expansion flags TRUE if element has an expansion
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputScriptElem(ScriptElement &element, int compare, UBool expansion)
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (compare) {
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case 0:
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (expansion) {
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='eq' title='[");
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='q' title='[");
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case -1:
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (expansion) {
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='ep' title='[");
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='p' title='[");
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case -2:
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (expansion) {
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='es' title='[");
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='s' title='[");
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (expansion) {
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='et' title='[");
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<tr><td class='t' title='[");
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t sortkey[32];
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_setStrength(COLLATOR_, UCOL_TERTIARY);
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_getSortKey(COLLATOR_, element.ch, element.count, sortkey, 32);
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int i = 0;
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (sortkey[i] != 0) {
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (sortkey[i] == 1) {
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, " | ");
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "%02x", sortkey[i]);
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i ++;
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "]'>");
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char       utf8[64];
843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar      nfc[32];
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t    length = unorm_normalize(element.ch, element.count, UNORM_NFC, 0, nfc,
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        32, &error);
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error normalizing contractions to NFC\n");
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_strToUTF8(utf8, 64, &length, nfc, length, &error);
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error converting UChar to utf8\n");
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "%s<br>", utf8);
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tt>");
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputUChar(element.ch, element.count);
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (compare == 0) {
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "</tt></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>Q</td><td>");
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (compare == -1) {
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "</tt></td><td>P</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>");
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (compare == -2) {
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "</tt></td><td>&nbsp;</td><td>S</td><td>&nbsp;</td><td>&nbsp;</td><td>");
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (compare == -3) {
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "</tt></td><td>&nbsp;</td><td>&nbsp;</td><td>T</td><td>&nbsp;</td><td>");
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    i = 0;
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (i < element.count) {
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        char    str[128];
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 codepoint;
876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF_NEXT_CHAR(element.ch, i, element.count, codepoint);
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t temp = u_charName(codepoint, U_UNICODE_CHAR_NAME, str, 128,
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                      &error);
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error getting character name\n");
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (element.tailored) {
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<b>");
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "%s", str);
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (element.tailored) {
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, " *</b>");
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (i < element.count) {
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, "<br>\n");
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</td></tr>\n");
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Checks if codepoint belongs to scripts
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script list
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param codepoint to test
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return TRUE if codepoint belongs to scripts
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool checkInScripts(UScriptCode script[], int scriptcount,
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     UChar32 codepoint)
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int i = 0; i < scriptcount; i ++) {
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (script[i] == USCRIPT_HAN && options[10].doesOccur) {
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ((codepoint >= 0x2E80 && codepoint <= 0x2EE4) ||
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                (codepoint >= 0x2A672 && codepoint <= 0x2A6D6)) {
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // reduce han
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return TRUE;
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (uscript_getScript(codepoint, &error) == script[i]) {
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return TRUE;
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error checking character in scripts\n");
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return FALSE;
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Checks if the set of codepoints belongs to the script
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script list
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptelem
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return TRUE if all codepoints belongs to the script
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline UBool checkInScripts(UScriptCode script[], int scriptcount,
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           ScriptElement scriptelem)
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int i = 0;
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (i < scriptelem.count) {
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32     codepoint;
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UTF_NEXT_CHAR(scriptelem.ch, i, scriptelem.count, codepoint);
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode  error = U_ZERO_ERROR;
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (checkInScripts(script, scriptcount, codepoint)) {
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return TRUE;
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Gets the script elements and contractions belonging to the script
952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param elems output list
953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param locale locale
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return number of script elements
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Add by Richard
956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint getScriptElementsFromExemplars(ScriptElement scriptelem[], const char* locale) {
958b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UErrorCode error = U_ZERO_ERROR;
959b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar32 codepoint = 0;
960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UResourceBundle* ures = ures_open(NULL, locale, &error);
962b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(error)) {
963b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "Can not find resource bundle for locale: %s\n", locale);
964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
965b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t length;
967b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar* exemplarChars = ures_getStringByKey(ures, "ExemplarCharacters", &length, &error);
968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(error)) {
970b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "Can not find ExemplarCharacters in resource bundle\n");
971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
972b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar* upperChars = new UChar[length * 2];
975b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (upperChars == 0) {
976b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "Memory error\n");
977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
978b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
980b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t destLength = u_strToUpper(upperChars, length * 2, exemplarChars, -1, locale, &error);
981b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(error)) {
982b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "Error when u_strToUpper() \n");
983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
984b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
985b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
986b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar* pattern = new UChar[length + destLength + 10];
987b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar left[2] = {0x005b, 0x0};
988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar right[2] = {0x005d, 0x0};
989b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pattern = u_strcpy(pattern, left);
990b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pattern = u_strcat(pattern, exemplarChars);
991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pattern = u_strcat(pattern, upperChars);
992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pattern = u_strcat(pattern, right);
993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeSet * uniset = new UnicodeSet(UnicodeString(pattern), error);
995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(error)) {
996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "Can not open USet \n");
997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
998b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeSetIterator* usetiter = new UnicodeSetIterator(*uniset);
1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1002b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t count = 0;
1003b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1004b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (usetiter -> next()) {
1005b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (usetiter -> isString()) {
1006b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UnicodeString strItem = usetiter -> getString();
1007b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            scriptelem[count].count = 0;
1009b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            for (int i = 0; i < strItem.length(); i++) {
1010b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                codepoint = strItem.char32At(i);
1011b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UTF16_APPEND_CHAR_UNSAFE(scriptelem[count].ch, scriptelem[count].count, codepoint);
1012b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                scriptelem[count].tailored = FALSE;
1013b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
1014b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else {
1015b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            codepoint = usetiter -> getCodepoint();
1016b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            scriptelem[count].count = 0;
1017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UTF16_APPEND_CHAR_UNSAFE(scriptelem[count].ch, scriptelem[count].count, codepoint);
1018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            scriptelem[count].tailored = FALSE;
1019b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
1020b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete []pattern;
1021b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1022b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        count++;
1023b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
1024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete []pattern;
1025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return count;
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Gets the script elements and contractions belonging to the script
1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script list
1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param elems output list
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return number of script elements
1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint getScriptElements(UScriptCode script[], int scriptcount,
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      ScriptElement scriptelem[])
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32    codepoint = 0;
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int        count     = 0;
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (codepoint <= UCHAR_MAX_VALUE) {
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (checkInScripts(script, scriptcount, codepoint)) {
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            scriptelem[count].count = 0;
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTF16_APPEND_CHAR_UNSAFE(scriptelem[count].ch,
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                     scriptelem[count].count, codepoint);
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            scriptelem[count].tailored = FALSE;
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count ++;
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error determining codepoint in script\n");
1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return -1;
1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        codepoint ++;
1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar           *current  = NULL;
1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         strength = 0;
1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chOffset = 0;
1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chLen    = 0;
1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exOffset = 0;
1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exLen    = 0;
1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixOffset = 0;
1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixLen    = 0;
1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint8_t          specs    = 0;
1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UBool            rstart   = TRUE;
1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColTokenParser  src;
1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColOptionSet    opts;
1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UParseError      parseError;
1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t  rulelength = ucol_getRulesEx(COLLATOR_, UCOL_FULL_RULES, NULL, 0);
1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.source       = (UChar *)malloc(sizeof(UChar) *
1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE));
1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    rulelength = ucol_getRulesEx(COLLATOR_, UCOL_FULL_RULES, src.source,
1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 rulelength);
1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.current      = src.source;
1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.end          = src.source + rulelength;
1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraCurrent = src.end;
1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraEnd     = src.end + UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.opts         = &opts;
1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	/*
1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	ucol_tok_parseNextToken(&src, &strength, &chOffset,
1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &chLen, &exOffset, &exLen,
1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &prefixOffset, &prefixLen,
1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &specs, rstart, &parseError,
1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &error)
1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    */
1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while ((current = ucol_tok_parseNextToken(&src, rstart, &parseError,
1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &error)) != NULL) {
1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // contractions handled here
1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (chLen > 1) {
1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_strncpy(scriptelem[count].ch, src.source + chOffset, chLen);
1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            scriptelem[count].count = chLen;
1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (checkInScripts(script, scriptcount, scriptelem[count])) {
1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                scriptelem[count].tailored     = FALSE;
1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                count ++;
1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rstart = FALSE;
1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error parsing rules: %s\n", u_errorName(error));
1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	// rule might have been reallocated, so delete this instead
1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    free(src.source);
1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return count;
1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint compareCodepoints(const void *elem1, const void *elem2)
1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *ch1 = ((ScriptElement *)elem1)->ch; // key
1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *ch2 = ((ScriptElement *)elem2)->ch;
1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ch1[((ScriptElement *)elem1)->count] = 0;
1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ch2[((ScriptElement *)elem2)->count] = 0;
1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // compare the 2 codepoints
1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return u_strcmp(ch1, ch2);
1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool hasSubNFD(ScriptElement &se, ScriptElement &key)
1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *ch1 = se.ch;
1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *ch2 = key.ch; // key
1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ch1[se.count] = 0;
1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ch2[key.count] = 0;
1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // compare the 2 codepoints
1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (u_strstr(ch1, ch2) != NULL) {
1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // check the decomposition
1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar      norm[32];
1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int        size  = unorm_normalize(ch1, se.count, UNORM_NFD, 0, norm, 32,
1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       &error);
1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error normalizing\n");
1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (u_strstr(norm, ch2) != NULL) {
1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Marks tailored elements
1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script list
1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptelem script element list
1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptelemlength size of the script element list
1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid markTailored(UScriptCode script[], int scriptcount,
1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  ScriptElement scriptelem[], int scriptelemlength)
1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          int32_t  rulelength;
1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar   *rule = ucol_getRules(COLLATOR_, &rulelength);
1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar           *current  = NULL;
1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         strength = 0;
1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chOffset = 0;
1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         chLen    = 0;
1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exOffset = 0;
1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         exLen    = 0;
1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixOffset = 0;
1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint32_t         prefixLen    = 0;
1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uint8_t          specs    = 0;
1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UBool            rstart   = TRUE;
1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColTokenParser  src;
1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UColOptionSet    opts;
1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          UParseError      parseError;
1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.opts         = &opts;
1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.source       = (UChar *)malloc(
1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               (rulelength + UCOL_TOK_EXTRA_RULE_SPACE_SIZE) * sizeof(UChar));
1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    memcpy(src.source, rule, rulelength * sizeof(UChar));
1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	src.current      = src.source;
1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.end          = (UChar *)src.source + rulelength;
1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraCurrent = src.end;
1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    src.extraEnd     = src.end + UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode    error = U_ZERO_ERROR;
1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while ((current = ucol_tok_parseNextToken(&src, rstart, &parseError,
1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &error)) != NULL) {
1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (chLen >= 1 && strength != UCOL_TOK_RESET) {
1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // skipping the reset characters and non useful stuff.
1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ScriptElement se;
1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_strncpy(se.ch, src.source + chOffset, chLen);
1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            se.count = chLen;
1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (checkInScripts(script, scriptcount, se)) {
1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /*
1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ScriptElement *tse = (ScriptElement *)bsearch(&se, scriptelem,
1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                              scriptelemlength,
1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                         sizeof(ScriptElement),
1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                         compareCodepoints);
1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                */
1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                for (int i = 0; i < scriptelemlength; i ++) {
1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (!scriptelem[i].tailored &&
1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        hasSubNFD(scriptelem[i], se)) {
1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        scriptelem[i].tailored = TRUE;
1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rstart = FALSE;
1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    free(src.source);
1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error parsing rules\n");
1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Checks if the collation iterator has more than 1 collation element
1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @parem coleiter collation element iterator
1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @return TRUE if collation iterator has more than 1 collation element
1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool hasExpansions(UCollationElements *coleiter)
1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t    ce    = ucol_next(coleiter, &error);
1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int        count = 0;
1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error getting next collation element\n");
1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (ce != UCOL_NULLORDER) {
1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((UCOL_PRIMARYORDER(ce) != 0) && !isContinuation(ce)) {
1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count ++;
1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count == 2) {
1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return TRUE;
1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ce = ucol_next(coleiter, &error);
1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error getting next collation element\n");
1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the footer for index.html
1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param file output file
1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputHTMLFooter()
1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</table>\n");
1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</body>\n");
1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</html>\n");
1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Serialize the codepoints from start to end into an html file.
1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Arranging them into ascending collation order.
1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script code list
1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//void serializeScripts(UScriptCode script[], int scriptcount)
1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//Richard
1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serializeScripts(UScriptCode script[], int scriptcount, const char* locale = NULL)
1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode  error  = U_ZERO_ERROR;
1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ScriptElement *scriptelem =
1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     (ScriptElement *)malloc(sizeof(ScriptElement) * 0x20000);
1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (scriptelem == NULL) {
1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Memory error\n");
1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int count = 0;
1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(locale) {
1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      count = getScriptElementsFromExemplars(scriptelem, locale);
1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      count = getScriptElements(script, scriptcount, scriptelem);
1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Sort script elements using Quicksort algorithm:
1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    qsort(scriptelem, count, sizeof(ScriptElement), compareCodepoints);
1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    markTailored(script, scriptcount, scriptelem, count);
1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Sort script elements using Quicksort algorithm:
1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    qsort(scriptelem, count, sizeof(ScriptElement), compareSortKey);
1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollationElements* coleiter = ucol_openElements(COLLATOR_,
1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                     scriptelem[0].ch,
1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                     scriptelem[0].count,
1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                     &error);
1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Error creating collation element iterator\n");
1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputScriptElem(scriptelem[0], -1, hasExpansions(coleiter));
1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int i = 0; i < count - 1; i ++) {
1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_setText(coleiter, scriptelem[i + 1].ch, scriptelem[i + 1].count,
1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     &error);
1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error setting text in collation element iterator\n");
1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        outputScriptElem(scriptelem[i + 1],
1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         compareSortKey(scriptelem + i, scriptelem + i + 1),
1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         hasExpansions(coleiter));
1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    free(scriptelem);
1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputHTMLFooter();
1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the header for the html
1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param locale name
1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param script
1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param scriptcount number of scripts
1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputHTMLHeader(const char *locale, UScriptCode script[],
1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int scriptcount)
1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<html>\n");
1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<head>\n");
1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<meta http-equiv=\"Content-Language\" content=\"en-us\">\n");
1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<link rel=\"stylesheet\" href=\"charts.css\" type=\"text/css\">\n");
1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<title>ICU Collation charts</title>\n");
1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<base target=\"main\">\n");
1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</head>\n");
1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<body bgcolor=#FFFFFF>\n");
1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<!--\n");
1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "This file contains sorted characters in ascending order according to the locale stated\n");
1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "If the character is in red, it is tailored in the collation rules.\n");
1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "Background colours have certain meanings:\n");
1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "White - equals the previous character\n");
1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "dark blue - primary greater than the previous character\n");
1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "blue - secondary greater than the previous character\n");
1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "light blue - tertiary greater than the previous character\n");
1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "--!>\n");
1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<table border=0>\n");
1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar      displayname[64];
1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode error = U_ZERO_ERROR;
1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t size = uloc_getDisplayName(locale, "en_US", displayname, 64, &error);
1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char       utf8displayname[128];
1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(error)) {
1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        utf8displayname[0] = 0;
1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t utf8size = 0;
1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        u_strToUTF8(utf8displayname, 128, &utf8size, displayname, size, &error);
1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tr><th>Locale</th><td class='noborder'>%s</td></tr>\n", utf8displayname);
1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tr><th>Script(s)</th>");
1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<td class='noborder'>");
1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int i = 0; i < scriptcount; i ++) {
1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(OUTPUT_, "%s", uscript_getName(script[i]));
1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (i + 1 != scriptcount) {
1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(OUTPUT_, ", ");
1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</td></tr>\n");
1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tr><th>Rules</th><td class='noborder'><a href=\"http://dev.icu-project.org/cgi-bin/viewcvs.cgi/*checkout*/icu/source/data/coll/%s.txt\">%s.txt</a></td></tr>\n", locale, locale);
1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UVersionInfo version;
1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucol_getVersion(COLLATOR_, version);
1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tr><th>Collator version</th><td class='noborder'>%d.%d.%d.%d</td></tr>\n",
1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      version[0], version[1], version[2], version[3]);
1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UColAttribute attr = UCOL_FRENCH_COLLATION;
1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (attr < UCOL_ATTRIBUTE_COUNT) {
1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UColAttributeValue value = ucol_getAttribute(COLLATOR_, attr, &error);
1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Error getting attribute\n");
1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (value != UCOL_DEFAULT) {
1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_FRENCH_COLLATION && value != UCOL_OFF) {
1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>French Collation</th><td class='noborder'>on, code %d</td></tr>\n", value);
1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_ALTERNATE_HANDLING && value != UCOL_NON_IGNORABLE) {
1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Alternate Handling</th><td class='noborder'>shifted, code%d</td></tr>\n", value);
1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_CASE_FIRST && value != UCOL_OFF) {
1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Case First</th><td class='noborder'>on, code %d</td></tr>\n", value);
1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_CASE_LEVEL && value != UCOL_OFF) {
1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Case Level</th><td class='noborder'>on, code %d</td></tr>\n", value);
1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_NORMALIZATION_MODE && value != UCOL_OFF) {
1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Normalization</th><td class='noborder'>on, code %d</td></tr>\n", value);
1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_STRENGTH && value != UCOL_TERTIARY) {
1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Strength</th><td class='noborder'>code %d</td></tr>\n", value);
1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (attr == UCOL_HIRAGANA_QUATERNARY_MODE && value != UCOL_OFF) {
1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(OUTPUT_, "<tr><th>Hiragana Quaternary</th><td class='noborder'>on, code %d</td></tr>\n", value);
1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        attr = (UColAttribute)(attr + 1);
1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Get UNIX-style time and display as number and string.
1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    time_t ltime;
1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    time( &ltime );
1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<tr><th>Date Generated</th><td class='noborder'>%s</td></tr>", ctime(&ltime));
1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "</table>\n");
1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<p><a href=help.html>How to read the table</a><br>\n");
1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "<a href=http://www.jtcsv.com/cgi-bin/icu-bugs/ target=new>Submit a bug</a></p>\n");
1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "\n<table>\n");
1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(OUTPUT_, "\n<tr><th>Codepoint</th><th>P</th><th>S</th><th>T</th><th>Q</th><th>Name</th></tr>\n");
1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the header for index.html
1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param file output file
1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputListHTMLHeader(FILE *file)
1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<html>\n");
1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<head>\n");
1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<meta http-equiv=\"Content-Language\" content=\"en-us\">\n");
1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<title>ICU Collation Charts</title>\n");
1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<base target=\"main\">\n");
1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "</head>\n");
1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<body bgcolor=#FFFFFF>\n");
1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<h2 align=center>ICU Collation Charts</h2>\n");
1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<p align=center>\n");
1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "<a href=http://www.unicode.org/charts/collation/ target=new>UCA Charts</a><br>");
1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Prints the footer for index.html
1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* @param file output file
1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid outputListHTMLFooter(FILE *file)
1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "</p>\n");
1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	//fprintf(file, "<center><image src=http://oss.software.ibm.com/icu/images/w24.gif></center>\n");
1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "</body>\n");
1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(file, "</html>\n");
1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Gets all scripts and serialize their codepoints into an html file.
1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid serializeScripts() {
1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char filename[128];
1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int  dirlength = 0;
1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[4].doesOccur) {
1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strcpy(filename, options[4].value);
1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dirlength = appendDirSeparator(filename);
1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      filename[0] = 0;
1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char    *locale;
1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          int32_t  localelist = 0;
1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          int32_t  localesize;
1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    localesize = ucol_countAvailable();
1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    locale     = ucol_getAvailable(localelist);
1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    strcat(filename, "list.html");
1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    FILE *list = fopen(filename, "w");
1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    filename[dirlength] = 0;
1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (list == NULL) {
1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Cannot open file: %s\n", filename);
1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputListHTMLHeader(list);
1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(list, "<blockquote>\n");
1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (TRUE) {
1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode error = U_ZERO_ERROR;
1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        COLLATOR_ = ucol_open(locale, &error);
1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(error)) {
1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, "Collator creation failed:");
1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stdout, u_errorName(error));
1486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((error != U_USING_FALLBACK_WARNING && // not tailored
1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            error != U_USING_DEFAULT_WARNING) ||
1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            checkLocaleForLanguage(locale)) {
1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(list, "<a href=%s.html>%s</a> ", locale, locale);
1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru	        setAttributes(COLLATOR_, &error);
1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               fprintf(stdout, "Collator attribute setting failed:");
1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               fprintf(stdout, u_errorName(error));
1496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho               break;
1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UScriptCode scriptcode[32];
1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uint32_t scriptcount = uscript_getCode(locale, scriptcode, 32,
1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                   &error);
1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(error)) {
1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Error getting lcale scripts\n");
1504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strcat(filename, locale);
1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strcat(filename, ".html");
1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            OUTPUT_ = fopen(filename, "w");
1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (OUTPUT_ == NULL) {
1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "Cannot open file:%s\n", filename);
1512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            outputHTMLHeader(locale, scriptcode, scriptcount);
1515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            fprintf(stdout, "%s\n", locale);
1516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(options[12].doesOccur) {
1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              // use whole scripts
1519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                serializeScripts(scriptcode, scriptcount);
1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              // use exemplar chars
1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              serializeScripts(scriptcode, scriptcount, locale);
1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fclose(OUTPUT_);
1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_close(COLLATOR_);
1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        filename[dirlength] = 0;
1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        localelist ++;
1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (localelist == localesize) {
1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        locale = ucol_getAvailable(localelist);
1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(list, "<br><a href=help.html>help</a><br>");
1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(list, "</blockquote>\n");
1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    outputListHTMLFooter(list);
1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fclose(list);
1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Main   --  process command line, read in and pre-process the test file,
1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*            call other functions to do the actual tests.
1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint main(int argc, char *argv[]) {
1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    argc = u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]),
1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       options);
1549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // error handling, printing usage message
1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (argc < 0) {
1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "error in command line argument: ");
1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, argv[-argc]);
1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "\n");
1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (argc < 0 || options[0].doesOccur || options[1].doesOccur) {
1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Usage: dumpce options...\n"
1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--help\n"
1559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Display this message.\n"
1560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--locale name|all\n"
1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    ICU locale to use. Default is en_US\n"
1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--serialize\n"
1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Serializes the collation elements in -locale or all locales available and outputs them into --outputdir/locale_ce.txt\n"
1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--destdir dir_name\n"
1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Path for outputing the serialized collation elements. Defaults to stdout if no defined\n"
1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--sourcedir dir_name\n"
1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Path for the input rule file for collation\n"
1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--attribute name=value,name=value...\n"
1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Pairs of attribute names and values for setting\n"
1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--rule filename\n"
1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Name of file containing the collation rules.\n"
1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--normalizaton mode\n"
1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    UNormalizationMode mode to be used.\n"
1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--scripts\n"
1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Codepoints from all scripts are sorted and serialized.\n"
1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--reducehan\n"
1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Only 200 Han script characters will be displayed with the use of --scripts.\n"
1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "--wholescripts\n"
1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        "    Show collation order for whole scripts instead of just for exemplar characters of a locale\n\n");
1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Example to generate *.txt files : dumpce --serialize --locale af --destdir /temp --attribute UCOL_STRENGTH=UCOL_DEFAULT_STRENGTH,4=17\n\n");
1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "Example to generate *.html files for oss web display: dumpce --scripts --destdir /temp --reducehan\n");
1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return argc < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    OUTPUT_ = stdout;
1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[6].doesOccur) {
1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stdout, "attributes %s\n", options[6].value);
1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parseAttributes();
1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[3].doesOccur) {
1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serialize();
1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[9].doesOccur) {
1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        serializeScripts();
1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0;
1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1599