164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/********************************************************************
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COPYRIGHT:
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Copyright (c) 2001-2010, International Business Machines Corporation and
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * others. All Rights Reserved.
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************/
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/************************************************************************
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   This test program is intended for testing Replaceable class.
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   11/28/2001  hshih       Ported back from Java.
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru************************************************************************/
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_TRANSLITERATION
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ittrans.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h>
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdlib.h>
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/rep.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "reptest.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//---------------------------------------------
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// runIndexedTest
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//---------------------------------------------
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * This is a test class that simulates styled text.
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * It associates a style number (0..65535) with each character,
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * and maintains that style in the normal fashion:
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * When setting text from raw string or characters,<br>
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Set the styles to the style of the first character replaced.<br>
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * If no characters are replaced, use the style of the previous character.<br>
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * If at start, use the following character<br>
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Otherwise use NO_STYLE.
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass TestReplaceable : public Replaceable {
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString chars;
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString styles;
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const UChar NO_STYLE;
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const UChar NO_STYLE_MARK;
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * The address of this static class variable serves as this class's ID
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * for ICU "poor man's RTTI".
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const char fgClassID;
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestReplaceable (const UnicodeString& text,
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     const UnicodeString& newStyles) {
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        chars = text;
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString s;
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int i = 0; i < text.length(); ++i) {
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (i < newStyles.length()) {
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                s.append(newStyles.charAt(i));
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (text.charAt(i) == NO_STYLE_MARK) {
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    s.append(NO_STYLE);
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    s.append((UChar)(i + 0x0031));
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        this->styles = s;
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual Replaceable *clone() const {
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return new TestReplaceable(chars, styles);
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ~TestReplaceable(void) {}
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString getStyles() {
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return styles;
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString toString() {
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString s = chars;
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        s.append("{");
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        s.append(styles);
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        s.append("}");
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return s;
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void extractBetween(int32_t start, int32_t limit, UnicodeString& result) const {
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        chars.extractBetween(start, limit, result);
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * ICU "poor man's RTTI", returns a UClassID for this class.
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     *
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @draft ICU 2.2
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * ICU "poor man's RTTI", returns a UClassID for the actual class.
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     *
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @draft ICU 2.2
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected:
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual int32_t getLength() const {
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return chars.length();
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UChar getCharAt(int32_t offset) const{
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return chars.charAt(offset);
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UChar32 getChar32At(int32_t offset) const{
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return chars.char32At(offset);
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void fixStyles(int32_t start, int32_t limit, int32_t newLen) {
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar newStyle = NO_STYLE;
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (start != limit && styles.charAt(start) != NO_STYLE) {
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            newStyle = styles.charAt(start);
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (start > 0 && getCharAt(start-1) != NO_STYLE_MARK) {
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            newStyle = styles.charAt(start-1);
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (limit < styles.length()) {
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            newStyle = styles.charAt(limit);
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // dumb implementation for now.
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString s;
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int i = 0; i < newLen; ++i) {
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // this doesn't really handle an embedded NO_STYLE_MARK
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // in the middle of a long run of characters right -- but
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // that case shouldn't happen anyway
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (getCharAt(start+i) == NO_STYLE_MARK) {
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                s.append(NO_STYLE);
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                s.append(newStyle);
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        styles.replaceBetween(start, limit, s);
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void handleReplaceBetween(int32_t start, int32_t limit, const UnicodeString& text) {
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString s;
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        this->extractBetween(start, limit, s);
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (s == text) return; // NO ACTION!
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        this->chars.replaceBetween(start, limit, text);
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fixStyles(start, limit, text.length());
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void copy(int32_t start, int32_t limit, int32_t dest) {
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        chars.copy(start, limit, dest);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        styles.copy(start, limit, dest);
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char TestReplaceable::fgClassID=0;
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UChar TestReplaceable::NO_STYLE  = 0x005F;
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UChar TestReplaceable::NO_STYLE_MARK = 0xFFFF;
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceableTest::runIndexedTest(int32_t index, UBool exec,
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                      const char* &name, char* /*par*/) {
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (index) {
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TESTCASE(0,TestReplaceableClass);
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default: name = ""; break;
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Dummy Replaceable implementation for better API/code coverage.
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass NoopReplaceable : public Replaceable {
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual int32_t getLength() const {
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UChar getCharAt(int32_t /*offset*/) const{
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0xffff;
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UChar32 getChar32At(int32_t /*offset*/) const{
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0xffff;
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void extractBetween(int32_t /*start*/, int32_t /*limit*/, UnicodeString& result) const {
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result.remove();
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void handleReplaceBetween(int32_t /*start*/, int32_t /*limit*/, const UnicodeString &/*text*/) {
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* do nothing */
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void copy(int32_t /*start*/, int32_t /*limit*/, int32_t /*dest*/) {
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* do nothing */
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate:
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const char fgClassID;
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char NoopReplaceable::fgClassID=0;
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ReplaceableTest::TestReplaceableClass(void) {
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UChar rawTestArray[][6] = {
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0041, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // ABCD
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0061, 0x0062, 0x0063, 0x0064, 0x00DF, 0x0000}, // abcd\u00DF
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0061, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // aBCD
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0041, 0x0300, 0x0045, 0x0300, 0x0000, 0x0000}, // A\u0300E\u0300
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x00C0, 0x00C8, 0x0000, 0x0000, 0x0000, 0x0000}, // \u00C0\u00C8
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("Lower", rawTestArray[0], "1234");
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("Title", rawTestArray[2], "1234");
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("NFC",   rawTestArray[3], "13");
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("NFD",   rawTestArray[4], "1122");
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("*(x) > A $1 B", rawTestArray[5], "11223");
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("*(x)(y) > A $2 B $1 C $2 D", rawTestArray[6], "113322334");
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    check("*(x)(y)(z) > A $3 B $2 C $1 D", rawTestArray[7], "114433225");
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Disabled for 2.4.  TODO Revisit in 2.6 or later.
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //check("*x > a", rawTestArray[8], "223"); // expect "123"?
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //check("*x > a", rawTestArray[9], "113"); // expect "123"?
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //check("*x > a", rawTestArray[10], "_33"); // expect "_23"?
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //check("*(x) > A $1 B", rawTestArray[11], "__223");
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // improve API/code coverage
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NoopReplaceable noop;
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Replaceable *p;
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if((p=noop.clone())!=NULL) {
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("Replaceable::clone() does not return NULL");
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete p;
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(!noop.hasMetaData()) {
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("Replaceable::hasMetaData() does not return TRUE");
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // try to call the compiler-provided
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // UMemory/UObject/Replaceable assignment operators
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NoopReplaceable noop2;
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    noop2=noop;
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if((p=noop2.clone())!=NULL) {
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("noop2.Replaceable::clone() does not return NULL");
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete p;
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // try to call the compiler-provided
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // UMemory/UObject/Replaceable copy constructors
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NoopReplaceable noop3(noop);
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if((p=noop3.clone())!=NULL) {
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("noop3.Replaceable::clone() does not return NULL");
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete p;
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ReplaceableTest::check(const UnicodeString& transliteratorName,
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            const UnicodeString& test,
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            const UnicodeString& shouldProduceStyles)
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestReplaceable *tr = new TestReplaceable(test, "");
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString expectedStyles = shouldProduceStyles;
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString original = tr->toString();
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Transliterator* t;
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (transliteratorName.charAt(0) == 0x2A /*'*'*/) {
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString rules(transliteratorName);
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        rules.remove(0,1);
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UParseError pe;
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD,
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            pe, status);
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // test clone()
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TestReplaceable *tr2 = (TestReplaceable *)tr->clone();
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(tr2 != NULL) {
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete tr;
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            tr = tr2;
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status);
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: failed to create the " + transliteratorName + " transliterator");
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tr;
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t->transliterate(*tr);
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString newStyles = tr->getStyles();
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (newStyles != expectedStyles) {
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL Styles: " + transliteratorName + "{" + original + "} => "
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            + tr->toString() + "; should be {" + expectedStyles + "}!");
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        log("OK: ");
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        log(transliteratorName);
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        log("(");
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        log(original);
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        log(") => ");
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(tr->toString());
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete tr;
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t;
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_TRANSLITERATION */
323