• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4  * COPYRIGHT:
5  * Copyright (c) 2005-2013, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  ********************************************************************/
8 /*
9 * File utexttst.c
10 *
11 * Modification History:
12 *
13 *   Date          Name               Description
14 *   06/13/2005    Andy Heninger      Creation
15 *******************************************************************************
16 */
17 
18 #include <stdbool.h>
19 
20 #include "unicode/utypes.h"
21 #include "unicode/utext.h"
22 #include "unicode/ustring.h"
23 #include "cintltst.h"
24 #include "memory.h"
25 #include "string.h"
26 
27 
28 static void TestAPI(void);
29 void addUTextTest(TestNode** root);
30 
31 
32 void
addUTextTest(TestNode ** root)33 addUTextTest(TestNode** root)
34 {
35   addTest(root, &TestAPI           ,    "tsutil/UTextTest/TestAPI");
36 }
37 
38 
39 #define TEST_ASSERT(x) UPRV_BLOCK_MACRO_BEGIN { \
40     if ((x)==false) { \
41         log_err("Test failure in file %s at line %d\n", __FILE__, __LINE__); \
42         gFailed = true; \
43     } \
44 } UPRV_BLOCK_MACRO_END
45 
46 
47 #define TEST_SUCCESS(status) UPRV_BLOCK_MACRO_BEGIN { \
48     if (U_FAILURE(status)) { \
49         log_err("Test failure in file %s at line %d. Error = \"%s\"\n", \
50                 __FILE__, __LINE__, u_errorName(status)); \
51         gFailed = true; \
52    } \
53 } UPRV_BLOCK_MACRO_END
54 
55 
56 
57 /*
58  *  TestAPI   verify that the UText API is accessible from C programs.
59  *            This is not intended to be a complete test of the API functionality.  That is
60  *            in the C++ intltest program.
61  *            This test is intended to check that everything can be accessed and built in
62  *            a pure C environment.
63  */
64 
65 
TestAPI(void)66 static void TestAPI(void) {
67     UErrorCode      status = U_ZERO_ERROR;
68     UBool           gFailed = false;
69     (void)gFailed;   /* Suppress set but not used warning. */
70 
71     /* Open    */
72     {
73         UText           utLoc = UTEXT_INITIALIZER;
74         const char *    cString = "\x61\x62\x63\x64";
75         UChar           uString[]  = {0x41, 0x42, 0x43, 0};
76         UText          *uta;
77         UText          *utb;
78         UChar           c;
79 
80         uta = utext_openUChars(NULL, uString, -1, &status);
81         TEST_SUCCESS(status);
82         c = utext_next32(uta);
83         TEST_ASSERT(c == 0x41);
84         utb = utext_close(uta);
85         TEST_ASSERT(utb == NULL);
86 
87         uta = utext_openUTF8(&utLoc, cString, -1, &status);
88         TEST_SUCCESS(status);
89         TEST_ASSERT(uta == &utLoc);
90 
91         uta = utext_close(&utLoc);
92         TEST_ASSERT(uta == &utLoc);
93     }
94 
95     /* utext_clone()  */
96     {
97         UChar   uString[]  = {0x41, 0x42, 0x43, 0};
98         int64_t len;
99         UText   *uta;
100         UText   *utb;
101 
102         status = U_ZERO_ERROR;
103         uta = utext_openUChars(NULL, uString, -1, &status);
104         TEST_SUCCESS(status);
105         utb = utext_clone(NULL, uta, false, false, &status);
106         TEST_SUCCESS(status);
107         TEST_ASSERT(utb != NULL);
108         TEST_ASSERT(utb != uta);
109         len = utext_nativeLength(uta);
110         TEST_ASSERT(len == u_strlen(uString));
111         utext_close(uta);
112         utext_close(utb);
113     }
114 
115     /* basic access functions  */
116     {
117         UChar     uString[]  = {0x41, 0x42, 0x43, 0};
118         UText     *uta;
119         UChar32   c;
120         int64_t   len;
121         UBool     b;
122         int64_t   i;
123 
124         status = U_ZERO_ERROR;
125         uta = utext_openUChars(NULL, uString, -1, &status);
126         TEST_ASSERT(uta!=NULL);
127         TEST_SUCCESS(status);
128         b = utext_isLengthExpensive(uta);
129         TEST_ASSERT(b==true);
130         len = utext_nativeLength(uta);
131         TEST_ASSERT(len == u_strlen(uString));
132         b = utext_isLengthExpensive(uta);
133         TEST_ASSERT(b==false);
134 
135         c = utext_char32At(uta, 0);
136         TEST_ASSERT(c==uString[0]);
137 
138         c = utext_current32(uta);
139         TEST_ASSERT(c==uString[0]);
140 
141         c = utext_next32(uta);
142         TEST_ASSERT(c==uString[0]);
143         c = utext_current32(uta);
144         TEST_ASSERT(c==uString[1]);
145 
146         c = utext_previous32(uta);
147         TEST_ASSERT(c==uString[0]);
148         c = utext_current32(uta);
149         TEST_ASSERT(c==uString[0]);
150 
151         c = utext_next32From(uta, 1);
152         TEST_ASSERT(c==uString[1]);
153         c = utext_next32From(uta, u_strlen(uString));
154         TEST_ASSERT(c==U_SENTINEL);
155 
156         c = utext_previous32From(uta, 2);
157         TEST_ASSERT(c==uString[1]);
158         i = utext_getNativeIndex(uta);
159         TEST_ASSERT(i == 1);
160 
161         utext_setNativeIndex(uta, 0);
162         b = utext_moveIndex32(uta, 1);
163         TEST_ASSERT(b==true);
164         i = utext_getNativeIndex(uta);
165         TEST_ASSERT(i==1);
166 
167         b = utext_moveIndex32(uta, u_strlen(uString)-1);
168         TEST_ASSERT(b==true);
169         i = utext_getNativeIndex(uta);
170         TEST_ASSERT(i==u_strlen(uString));
171 
172         b = utext_moveIndex32(uta, 1);
173         TEST_ASSERT(b==false);
174         i = utext_getNativeIndex(uta);
175         TEST_ASSERT(i==u_strlen(uString));
176 
177         utext_setNativeIndex(uta, 0);
178         c = UTEXT_NEXT32(uta);
179         TEST_ASSERT(c==uString[0]);
180         c = utext_current32(uta);
181         TEST_ASSERT(c==uString[1]);
182 
183         c = UTEXT_PREVIOUS32(uta);
184         TEST_ASSERT(c==uString[0]);
185         c = UTEXT_PREVIOUS32(uta);
186         TEST_ASSERT(c==U_SENTINEL);
187 
188 
189         utext_close(uta);
190     }
191 
192     {
193         /*
194          * UText opened on a NULL string with zero length
195          */
196         UText    *uta;
197         UChar32   c;
198 
199         status = U_ZERO_ERROR;
200         uta = utext_openUChars(NULL, NULL, 0, &status);
201         TEST_SUCCESS(status);
202         c = UTEXT_NEXT32(uta);
203         TEST_ASSERT(c == U_SENTINEL);
204         utext_close(uta);
205 
206         uta = utext_openUTF8(NULL, NULL, 0, &status);
207         TEST_SUCCESS(status);
208         c = UTEXT_NEXT32(uta);
209         TEST_ASSERT(c == U_SENTINEL);
210         utext_close(uta);
211     }
212 
213 
214     {
215         /*
216          * extract
217          */
218         UText     *uta;
219         UChar     uString[]  = {0x41, 0x42, 0x43, 0};
220         UChar     buf[100];
221         int32_t   i;
222         /* Test pinning of input bounds */
223         UChar     uString2[]  = {0x41, 0x42, 0x43, 0x44, 0x45,
224                                  0x46, 0x47, 0x48, 0x49, 0x4A, 0};
225         UChar *   uString2Ptr = uString2 + 5;
226 
227         status = U_ZERO_ERROR;
228         uta = utext_openUChars(NULL, uString, -1, &status);
229         TEST_SUCCESS(status);
230 
231         status = U_ZERO_ERROR;
232         i = utext_extract(uta, 0, 100, NULL, 0, &status);
233         TEST_ASSERT(status==U_BUFFER_OVERFLOW_ERROR);
234         TEST_ASSERT(i == u_strlen(uString));
235 
236         status = U_ZERO_ERROR;
237         memset(buf, 0, sizeof(buf));
238         i = utext_extract(uta, 0, 100, buf, 100, &status);
239         TEST_SUCCESS(status);
240         TEST_ASSERT(i == u_strlen(uString));
241         i = u_strcmp(uString, buf);
242         TEST_ASSERT(i == 0);
243         utext_close(uta);
244 
245         /* Test pinning of input bounds */
246         status = U_ZERO_ERROR;
247         uta = utext_openUChars(NULL, uString2Ptr, -1, &status);
248         TEST_SUCCESS(status);
249 
250         status = U_ZERO_ERROR;
251         memset(buf, 0, sizeof(buf));
252         i = utext_extract(uta, -3, 20, buf, 100, &status);
253         TEST_SUCCESS(status);
254         TEST_ASSERT(i == u_strlen(uString2Ptr));
255         i = u_strcmp(uString2Ptr, buf);
256         TEST_ASSERT(i == 0);
257         utext_close(uta);
258     }
259 
260     {
261         /*
262          *  Copy, Replace, isWritable
263          *    Can't create an editable UText from plain C, so all we
264          *    can easily do is check that errors returned.
265          */
266         UText     *uta;
267         UChar     uString[]  = {0x41, 0x42, 0x43, 0};
268         UBool     b;
269 
270         status = U_ZERO_ERROR;
271         uta = utext_openUChars(NULL, uString, -1, &status);
272         TEST_SUCCESS(status);
273 
274         b = utext_isWritable(uta);
275         TEST_ASSERT(b == false);
276 
277         b = utext_hasMetaData(uta);
278         TEST_ASSERT(b == false);
279 
280         utext_replace(uta,
281                       0, 1,     /* start, limit */
282                       uString, -1,  /* replacement, replacement length */
283                       &status);
284         TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
285 
286 
287         utext_copy(uta,
288                    0, 1,         /* start, limit      */
289                    2,            /* destination index */
290                    false,        /* move flag         */
291                    &status);
292         TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
293 
294         utext_close(uta);
295     }
296 
297     {
298         // utext_equals() checks for the same type of text provider,
299         // same string pointer(!), and same index.
300         status = U_ZERO_ERROR;
301         const UChar *s = u"aßカ��";
302         UText *ut1 = utext_openUChars(NULL, s, -1, &status);
303         UText *ut2 = utext_openUChars(NULL, s, 5, &status);
304         TEST_SUCCESS(status);
305         TEST_ASSERT(utext_equals(ut1, ut2));
306         UChar32 c = utext_next32(ut1);
307         TEST_ASSERT(c == u'a');
308         TEST_ASSERT(!utext_equals(ut1, ut2));  // indexes out of sync
309         c = utext_next32(ut2);
310         TEST_ASSERT(c == u'a');
311         TEST_ASSERT(utext_equals(ut1, ut2));  // back in sync
312         utext_close(ut1);
313         utext_close(ut2);
314     }
315 }
316