1// Copyright (C) 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8/*******************************************************************************
9*
10* File creststn.c
11*
12* Modification History:
13*        Name              Date               Description
14*   Madhu Katragadda    05/09/2000   Ported Tests for New ResourceBundle API
15*   Madhu Katragadda    05/24/2000   Added new tests to test RES_BINARY for collationElements
16********************************************************************************
17*/
18
19
20#include <time.h>
21#include "unicode/utypes.h"
22#include "cintltst.h"
23#include "unicode/putil.h"
24#include "unicode/ustring.h"
25#include "unicode/ucnv.h"
26#include "string.h"
27#include "cmemory.h"
28#include "cstring.h"
29#include "unicode/uchar.h"
30#include "ucol_imp.h"  /* for U_ICUDATA_COLL */
31#include "ubrkimpl.h" /* for U_ICUDATA_BRKITR */
32#define RESTEST_HEAP_CHECK 0
33
34#include "unicode/uloc.h"
35#include "unicode/ulocdata.h"
36#include "uresimp.h"
37#include "creststn.h"
38#include "unicode/ctest.h"
39#include "ucbuf.h"
40#include "ureslocs.h"
41
42static int32_t pass;
43static int32_t fail;
44
45/*****************************************************************************/
46/**
47 * Return a random unsigned long l where 0N <= l <= ULONG_MAX.
48 */
49
50static uint32_t
51randul()
52{
53    uint32_t l=0;
54    int32_t i;
55    static UBool initialized = FALSE;
56    if (!initialized)
57    {
58        srand((unsigned)time(NULL));
59        initialized = TRUE;
60    }
61    /* Assume rand has at least 12 bits of precision */
62
63    for (i=0; i<sizeof(l); ++i)
64        ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4);
65    return l;
66}
67
68/**
69 * Return a random double x where 0.0 <= x < 1.0.
70 */
71static double
72randd()
73{
74    return ((double)randul()) / UINT32_MAX;
75}
76
77/**
78 * Return a random integer i where 0 <= i < n.
79 */
80static int32_t randi(int32_t n)
81{
82    return (int32_t)(randd() * n);
83}
84/***************************************************************************************/
85/**
86 * Convert an integer, positive or negative, to a character string radix 10.
87 */
88static char*
89itoa1(int32_t i, char* buf)
90{
91  char *p = 0;
92  char* result = buf;
93  /* Handle negative */
94  if(i < 0) {
95    *buf++ = '-';
96    i = -i;
97  }
98
99  /* Output digits in reverse order */
100  p = buf;
101  do {
102    *p++ = (char)('0' + (i % 10));
103    i /= 10;
104  }
105  while(i);
106  *p-- = 0;
107
108  /* Reverse the string */
109  while(buf < p) {
110    char c = *buf;
111    *buf++ = *p;
112    *p-- = c;
113  }
114
115  return result;
116}
117static const int32_t kERROR_COUNT = -1234567;
118static const UChar kERROR[] = { 0x0045 /*E*/, 0x0052 /*'R'*/, 0x0052 /*'R'*/,
119             0x004F /*'O'*/, 0x0052/*'R'*/, 0x0000 /*'\0'*/};
120
121/*****************************************************************************/
122
123enum E_Where
124{
125  e_Root,
126  e_te,
127  e_te_IN,
128  e_Where_count
129};
130typedef enum E_Where E_Where;
131/*****************************************************************************/
132
133#define CONFIRM_EQ(actual,expected) if (u_strcmp(expected,actual)==0){ record_pass(); } else { record_fail(); log_err("%s  returned  %s  instead of %s\n", action, austrdup(actual), austrdup(expected)); }
134#define CONFIRM_INT_EQ(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); log_err("%s returned %d instead of %d\n",  action, actual, expected); }
135#define CONFIRM_INT_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); log_err("%s returned %d instead of x >= %d\n",  action, actual, expected); }
136#define CONFIRM_INT_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); log_err("%s returned %d instead of x != %d\n",  action, actual, expected); }
137/*#define CONFIRM_ErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail();  log_err("%s returned  %s  instead of %s\n", action, myErrorName(actual), myErrorName(expected)); } */
138static void
139CONFIRM_ErrorCode(UErrorCode actual,UErrorCode expected)
140{
141  if ((expected)==(actual))
142  {
143    record_pass();
144  } else {
145    record_fail();
146    /*log_err("%s returned  %s  instead of %s\n", action, myErrorName(actual), myErrorName(expected)); */
147    log_err("returned  %s  instead of %s\n", myErrorName(actual), myErrorName(expected));
148  }
149}
150
151
152/* Array of our test objects */
153
154static struct
155{
156  const char* name;
157  UErrorCode expected_constructor_status;
158  E_Where where;
159  UBool like[e_Where_count];
160  UBool inherits[e_Where_count];
161}
162param[] =
163{
164  /* "te" means test */
165  /* "IN" means inherits */
166  /* "NE" or "ne" means "does not exist" */
167
168  { "root",         U_ZERO_ERROR,             e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
169  { "te",           U_ZERO_ERROR,             e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE  } },
170  { "te_IN",        U_ZERO_ERROR,             e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE   } },
171  { "te_NE",        U_USING_FALLBACK_WARNING, e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE  } },
172  { "te_IN_NE",     U_USING_FALLBACK_WARNING, e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE   } },
173  { "ne",           U_USING_DEFAULT_WARNING,  e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
174};
175
176static int32_t bundles_count = UPRV_LENGTHOF(param);
177
178
179
180/*static void printUChars(UChar*);*/
181static void TestDecodedBundle(void);
182static void TestGetKeywordValues(void);
183static void TestGetFunctionalEquivalent(void);
184static void TestCLDRStyleAliases(void);
185static void TestFallbackCodes(void);
186static void TestGetUTF8String(void);
187static void TestCLDRVersion(void);
188
189/***************************************************************************************/
190
191/* Array of our test objects */
192
193void addNEWResourceBundleTest(TestNode** root)
194{
195    addTest(root, &TestErrorCodes,            "tsutil/creststn/TestErrorCodes");
196#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
197    addTest(root, &TestEmptyBundle,           "tsutil/creststn/TestEmptyBundle");
198    addTest(root, &TestConstruction1,         "tsutil/creststn/TestConstruction1");
199    addTest(root, &TestResourceBundles,       "tsutil/creststn/TestResourceBundles");
200    addTest(root, &TestNewTypes,              "tsutil/creststn/TestNewTypes");
201    addTest(root, &TestEmptyTypes,            "tsutil/creststn/TestEmptyTypes");
202    addTest(root, &TestBinaryCollationData,   "tsutil/creststn/TestBinaryCollationData");
203    addTest(root, &TestAPI,                   "tsutil/creststn/TestAPI");
204    addTest(root, &TestErrorConditions,       "tsutil/creststn/TestErrorConditions");
205    addTest(root, &TestDecodedBundle,         "tsutil/creststn/TestDecodedBundle");
206    addTest(root, &TestResourceLevelAliasing, "tsutil/creststn/TestResourceLevelAliasing");
207    addTest(root, &TestDirectAccess,          "tsutil/creststn/TestDirectAccess");
208    addTest(root, &TestTicket9804,            "tsutil/creststn/TestTicket9804");
209    addTest(root, &TestXPath,                 "tsutil/creststn/TestXPath");
210    addTest(root, &TestCLDRStyleAliases,      "tsutil/creststn/TestCLDRStyleAliases");
211    addTest(root, &TestFallbackCodes,         "tsutil/creststn/TestFallbackCodes");
212    addTest(root, &TestGetUTF8String,         "tsutil/creststn/TestGetUTF8String");
213    addTest(root, &TestCLDRVersion,           "tsutil/creststn/TestCLDRVersion");
214    addTest(root, &TestPreventFallback,       "tsutil/creststn/TestPreventFallback");
215#endif
216    addTest(root, &TestFallback,              "tsutil/creststn/TestFallback");
217    addTest(root, &TestGetVersion,            "tsutil/creststn/TestGetVersion");
218    addTest(root, &TestGetVersionColl,        "tsutil/creststn/TestGetVersionColl");
219    addTest(root, &TestAliasConflict,         "tsutil/creststn/TestAliasConflict");
220    addTest(root, &TestGetKeywordValues,      "tsutil/creststn/TestGetKeywordValues");
221    addTest(root, &TestGetFunctionalEquivalent,"tsutil/creststn/TestGetFunctionalEquivalent");
222    addTest(root, &TestJB3763,                "tsutil/creststn/TestJB3763");
223    addTest(root, &TestStackReuse,            "tsutil/creststn/TestStackReuse");
224}
225
226
227/***************************************************************************************/
228static const char* norwayNames[] = {
229    "no_NO_NY",
230    "no_NO",
231    "no",
232    "nn_NO",
233    "nn",
234    "nb_NO",
235    "nb"
236};
237
238static const char* norwayLocales[] = {
239    "nn_NO",
240    "nb_NO",
241    "nb",
242    "nn_NO",
243    "nn",
244    "nb_NO",
245    "nb"
246};
247
248static void checkStatus(int32_t line, UErrorCode expected, UErrorCode status) {
249  if(U_FAILURE(status)) {
250    log_data_err("Resource not present, cannot test (%s:%d)\n", __FILE__, line);
251  }
252  if(status != expected) {
253    log_err_status(status, "%s:%d: Expected error code %s, got error code %s\n", __FILE__, line, u_errorName(expected), u_errorName(status));
254  }
255}
256
257static void TestErrorCodes(void) {
258  UErrorCode status = U_USING_DEFAULT_WARNING;
259
260  UResourceBundle *r = NULL, *r2 = NULL;
261
262  /* First check with ICUDATA */
263  /* first bundle should return fallback warning */
264  r = ures_open(NULL, "ti_ER_ASSAB", &status);
265  checkStatus(__LINE__, U_USING_FALLBACK_WARNING, status);
266  ures_close(r);
267
268  /* this bundle should return zero error, so it shouldn't change the status */
269  status = U_USING_DEFAULT_WARNING;
270  r = ures_open(NULL, "ti_ER", &status);
271  checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
272
273  /* we look up the resource which is aliased, but it lives in fallback */
274
275  if(U_SUCCESS(status) && r != NULL) {
276    status = U_USING_DEFAULT_WARNING;
277    r2 = ures_getByKey(r, "ExemplarCharacters", NULL, &status);  /* ExemplarCharacters lives in ti */
278    checkStatus(__LINE__, U_USING_FALLBACK_WARNING, status);
279  }
280  ures_close(r);
281
282  /* this bundle should return zero error, so it shouldn't change the status */
283  status = U_USING_DEFAULT_WARNING;
284  r = ures_open(U_ICUDATA_REGION, "ti", &status);
285  checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
286  ures_close(r);
287
288  status = U_USING_FALLBACK_WARNING;
289  r = ures_open(NULL, "nolocale", &status);
290  checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
291  ures_close(r);
292  ures_close(r2);
293
294#if !UCONFIG_NO_COLLATION
295  /** Now, with the collation bundle **/
296
297  /* first bundle should return fallback warning */
298  r = ures_open(U_ICUDATA_COLL, "sr_YU_VOJVODINA", &status);
299  checkStatus(__LINE__, U_USING_FALLBACK_WARNING, status);
300  ures_close(r);
301
302  /* this bundle should return zero error, so it shouldn't change the status */
303  status = U_USING_FALLBACK_WARNING;
304  r = ures_open(U_ICUDATA_COLL, "sr", &status);
305  checkStatus(__LINE__, U_USING_FALLBACK_WARNING, status);
306
307  /* we look up the resource which is aliased  */
308  if(U_SUCCESS(status) && r != NULL) {
309    status = U_USING_DEFAULT_WARNING;
310    r2 = ures_getByKey(r, "collations", NULL, &status);
311    checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
312  }
313  ures_close(r);
314
315  /* this bundle should return zero error, so it shouldn't change the status */
316  status = U_USING_DEFAULT_WARNING;
317  r = ures_open(U_ICUDATA_COLL, "sr", &status);
318  checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
319
320  /* we look up the resource which is aliased and at our level */
321  if(U_SUCCESS(status) && r != NULL) {
322    status = U_USING_DEFAULT_WARNING;
323    r2 = ures_getByKey(r, "collations", r2, &status);
324    checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
325  }
326  ures_close(r);
327
328  status = U_USING_FALLBACK_WARNING;
329  r = ures_open(U_ICUDATA_COLL, "nolocale", &status);
330  checkStatus(__LINE__, U_USING_DEFAULT_WARNING, status);
331  ures_close(r);
332  ures_close(r2);
333#endif  /* !UCONFIG_NO_COLLATION */
334}
335
336static void TestAliasConflict(void) {
337    UErrorCode status = U_ZERO_ERROR;
338    UResourceBundle *he = NULL;
339    UResourceBundle *iw = NULL;
340    UResourceBundle *norway = NULL;
341    const UChar *result = NULL;
342    int32_t resultLen;
343    uint32_t size = 0;
344    uint32_t i = 0;
345    const char *realName = NULL;
346
347    he = ures_open(NULL, "he", &status);
348    iw = ures_open(NULL, "iw", &status);
349    if(U_FAILURE(status)) {
350        log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
351    }
352    ures_close(iw);
353    result = ures_getStringByKey(he, "ExemplarCharacters", &resultLen, &status);
354    if(U_FAILURE(status) || result == NULL) {
355        log_err_status(status, "Failed to get resource ExemplarCharacters with %s\n", myErrorName(status));
356    }
357    ures_close(he);
358
359    size = UPRV_LENGTHOF(norwayNames);
360    for(i = 0; i < size; i++) {
361        status = U_ZERO_ERROR;
362        norway = ures_open(NULL, norwayNames[i], &status);
363        if(U_FAILURE(status)) {
364            log_err_status(status, "Failed to get resource with %s for %s\n", myErrorName(status), norwayNames[i]);
365            continue;
366        }
367        realName = ures_getLocale(norway, &status);
368        log_verbose("ures_getLocale(\"%s\")=%s\n", norwayNames[i], realName);
369        if(realName == NULL || strcmp(norwayLocales[i], realName) != 0) {
370            log_data_err("Wrong locale name for %s, expected %s, got %s\n", norwayNames[i], norwayLocales[i], realName);
371        }
372        ures_close(norway);
373    }
374}
375
376static void TestDecodedBundle(){
377
378    UErrorCode error = U_ZERO_ERROR;
379
380    UResourceBundle* resB;
381
382    const UChar* srcFromRes;
383    int32_t len;
384    static const UChar uSrc[] = {
385        0x0009,0x092F,0x0941,0x0928,0x0947,0x0938,0x094D,0x0915,0x094B,0x0020,0x002E,0x0915,0x0947,0x0020,0x002E,0x090F,
386        0x0915,0x0020,0x002E,0x0905,0x0927,0x094D,0x092F,0x092F,0x0928,0x0020,0x002E,0x0915,0x0947,0x0020,0x0905,0x0928,
387        0x0941,0x0938,0x093E,0x0930,0x0020,0x0031,0x0039,0x0039,0x0030,0x0020,0x0924,0x0915,0x0020,0x0915,0x0902,0x092A,
388        0x094D,0x092F,0x0942,0x091F,0x0930,0x002D,0x092A,0x094D,0x0930,0x092C,0x0902,0x0927,0x093F,0x0924,0x0020,0x0938,
389        0x0942,0x091A,0x0928,0x093E,0x092A,0x094D,0x0930,0x0923,0x093E,0x0932,0x0940,0x0020,0x002E,0x0915,0x0947,0x0020,
390        0x002E,0x092F,0x094B,0x0917,0x0926,0x093E,0x0928,0x0020,0x002E,0x0915,0x0947,0x0020,0x002E,0x092B,0x0932,0x0938,
391        0x094D,0x0935,0x0930,0x0942,0x092A,0x0020,0x002E,0x0935,0x093F,0x0936,0x094D,0x0935,0x0020,0x002E,0x092E,0x0947,
392        0x0902,0x0020,0x002E,0x0938,0x093E,0x0932,0x093E,0x0928,0x093E,0x0020,0x002E,0x0032,0x0032,0x0030,0x0030,0x0020,
393        0x0905,0x0930,0x092C,0x0020,0x0930,0x0941,0x092A,0x092F,0x0947,0x0020,0x092E,0x0942,0x0932,0x094D,0x092F,0x0915,
394        0x0940,0x0020,0x002E,0x0034,0x0935,0x0938,0x094D,0x0924,0x0941,0x0913,0x0902,0x0020,0x002E,0x0034,0x0915,0x093E,
395        0x0020,0x002E,0x0034,0x0909,0x0924,0x094D,0x092A,0x093E,0x0926,0x0928,0x0020,0x002E,0x0034,0x0939,0x094B,0x0917,
396        0x093E,0x002C,0x0020,0x002E,0x0033,0x091C,0x092C,0x0915,0x093F,0x0020,0x002E,0x0033,0x0915,0x0902,0x092A,0x094D,
397        0x092F,0x0942,0x091F,0x0930,0x0020,0x002E,0x0033,0x0915,0x093E,0x0020,0x002E,0x0033,0x0915,0x0941,0x0932,0x0020,
398        0x002E,0x0033,0x092F,0x094B,0x0917,0x0926,0x093E,0x0928,0x0020,0x002E,0x0033,0x0907,0x0938,0x0938,0x0947,0x0915,
399        0x0939,0x093F,0x0020,0x002E,0x002F,0x091C,0x094D,0x092F,0x093E,0x0926,0x093E,0x0020,0x002E,0x002F,0x0939,0x094B,
400        0x0917,0x093E,0x0964,0x0020,0x002E,0x002F,0x0905,0x0928,0x0941,0x0938,0x0902,0x0927,0x093E,0x0928,0x0020,0x002E,
401        0x002F,0x0915,0x0940,0x0020,0x002E,0x002F,0x091A,0x0930,0x092E,0x0020,0x0938,0x0940,0x092E,0x093E,0x0913,0x0902,
402        0x0020,0x092A,0x0930,0x0020,0x092A,0x0939,0x0941,0x0902,0x091A,0x0928,0x0947,0x0020,0x0915,0x0947,0x0020,0x0932,
403        0x093F,0x090F,0x0020,0x0915,0x0902,0x092A,0x094D,0x092F,0x0942,0x091F,0x0930,0x090F,0x0915,0x0020,0x002E,0x002F,
404        0x0906,0x092E,0x0020,0x002E,0x002F,0x091C,0x0930,0x0942,0x0930,0x0924,0x0020,0x002E,0x002F,0x091C,0x0948,0x0938,
405        0x093E,0x0020,0x092C,0x0928,0x0020,0x0917,0x092F,0x093E,0x0020,0x0939,0x0948,0x0964,0x0020,0x092D,0x093E,0x0930,
406        0x0924,0x0020,0x092E,0x0947,0x0902,0x0020,0x092D,0x0940,0x002C,0x0020,0x0916,0x093E,0x0938,0x0915,0x0930,0x0020,
407        0x092E,0x094C,0x091C,0x0942,0x0926,0x093E,0x0020,0x0938,0x0930,0x0915,0x093E,0x0930,0x0928,0x0947,0x002C,0x0020,
408        0x0915,0x0902,0x092A,0x094D,0x092F,0x0942,0x091F,0x0930,0x0020,0x0915,0x0947,0x0020,0x092A,0x094D,0x0930,0x092F,
409        0x094B,0x0917,0x0020,0x092A,0x0930,0x0020,0x091C,0x092C,0x0930,0x0926,0x0938,0x094D,0x0924,0x0020,0x090F,0x095C,
410        0x0020,0x0932,0x0917,0x093E,0x092F,0x0940,0x0020,0x0939,0x0948,0x002C,0x0020,0x0915,0x093F,0x0902,0x0924,0x0941,
411        0x0020,0x0907,0x0938,0x0915,0x0947,0x0020,0x0938,0x0930,0x092A,0x091F,0x0020,0x0926,0x094C,0x095C,0x0932,0x0917,
412        0x093E,0x0928,0x0947,0x0020,0x002E,0x0032,0x0915,0x0947,0x0020,0x002E,0x0032,0x0932,0x093F,0x090F,0x0020,0x002E,
413        0x0032,0x0915,0x094D,0x092F,0x093E,0x0020,0x002E,0x0032,0x0938,0x092A,0x093E,0x091F,0x0020,0x002E,0x0032,0x0930,
414        0x093E,0x0938,0x094D,0x0924,0x093E,0x0020,0x002E,0x0032,0x0909,0x092A,0x0932,0x092C,0x094D,0x0927,0x0020,0x002E,
415        0x0939,0x0948,0x002C,0x0020,0x002E,0x0905,0x0925,0x0935,0x093E,0x0020,0x002E,0x0935,0x093F,0x0936,0x094D,0x0935,
416        0x0020,0x002E,0x092E,0x0947,0x0902,0x0020,0x002E,0x0915,0x0902,0x092A,0x094D,0x092F,0x0942,0x091F,0x0930,0x0020,
417        0x002E,0x0915,0x0940,0x0938,0x092B,0x0932,0x0924,0x093E,0x0020,0x002E,0x0033,0x0935,0x0020,0x002E,0x0033,0x0935,
418        0x093F,0x092B,0x0932,0x0924,0x093E,0x0020,0x002E,0x0033,0x0938,0x0947,0x0020,0x002E,0x0033,0x0938,0x092C,0x0915,
419        0x0020,0x002E,0x0033,0x0932,0x0947,0x0020,0x002E,0x0033,0x0915,0x0930,0x0020,0x002E,0x0033,0x0915,0x094D,0x092F,
420        0x093E,0x0020,0x002E,0x0033,0x0939,0x092E,0x0020,0x002E,0x0033,0x0907,0x0938,0x0915,0x093E,0x0020,0x002E,0x0033,
421        0x092F,0x0941,0x0915,0x094D,0x0924,0x093F,0x092A,0x0942,0x0930,0x094D,0x0923,0x0020,0x002E,0x0032,0x0935,0x093F,
422        0x0938,0x094D,0x0924,0x093E,0x0930,0x0020,0x0905,0x092A,0x0947,0x0915,0x094D,0x0937,0x093F,0x0924,0x0020,0x0915,
423        0x0930,0x0020,0x0938,0x0915,0x0947,0x0902,0x0917,0x0947,0x0020,0x003F,0x0020,
424        0
425    };
426
427    /* pre-flight */
428    int32_t num =0;
429    const char *testdatapath = loadTestData(&error);
430    resB = ures_open(testdatapath, "encoded", &error);
431    srcFromRes=tres_getString(resB,-1,"str",&len,&error);
432    if(U_FAILURE(error)){
433        log_data_err("Could not find encoded.res from test data bundle. Error: %s\n", u_errorName(error));
434        ures_close(resB);
435        return;
436    }
437    if(u_strncmp(srcFromRes,uSrc,len)!=0){
438        log_err("Genrb produced res files after decoding failed\n");
439    }
440    while(num<len){
441        if(uSrc[num]!=srcFromRes[num]){
442            log_verbose(" Expected:  0x%04X Got: 0x%04X \n", uSrc[num],srcFromRes[num]);
443        }
444        num++;
445    }
446    if (len != u_strlen(uSrc)) {
447        log_err("Genrb produced a string larger than expected\n");
448    }
449    ures_close(resB);
450}
451
452static void TestNewTypes() {
453    UResourceBundle* theBundle = NULL;
454    char action[256];
455    const char* testdatapath;
456    UErrorCode status = U_ZERO_ERROR;
457    UResourceBundle* res = NULL;
458    uint8_t *binResult = NULL;
459    int32_t len = 0;
460    int32_t i = 0;
461    int32_t intResult = 0;
462    uint32_t uintResult = 0;
463    const UChar *empty = NULL;
464    const UChar *zeroString;
465    UChar expected[] = { 'a','b','c','\0','d','e','f' };
466    const char* expect ="tab:\t cr:\r ff:\f newline:\n backslash:\\\\ quote=\\\' doubleQuote=\\\" singlequoutes=''";
467    UChar uExpect[200];
468
469    testdatapath=loadTestData(&status);
470
471    if(U_FAILURE(status))
472    {
473        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
474        return;
475    }
476
477    theBundle = ures_open(testdatapath, "testtypes", &status);
478
479    empty = tres_getString(theBundle, -1, "emptystring", &len, &status);
480    if(empty && (*empty != 0 || len != 0)) {
481      log_err("Empty string returned invalid value\n");
482    }
483
484    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
485
486    CONFIRM_INT_NE(theBundle, NULL);
487
488    /* This test reads the string "abc\u0000def" from the bundle   */
489    /* if everything is working correctly, the size of this string */
490    /* should be 7. Everything else is a wrong answer, esp. 3 and 6*/
491
492    strcpy(action, "getting and testing of string with embeded zero");
493    res = ures_getByKey(theBundle, "zerotest", res, &status);
494    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
495    CONFIRM_INT_EQ(ures_getType(res), URES_STRING);
496    zeroString=tres_getString(res, -1, NULL, &len, &status);
497    if(U_SUCCESS(status)){
498        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
499        CONFIRM_INT_EQ(len, 7);
500        CONFIRM_INT_NE(len, 3);
501    }
502    for(i=0;i<len;i++){
503        if(zeroString[i]!= expected[i]){
504            log_verbose("Output did not match Expected: \\u%4X Got: \\u%4X", expected[i], zeroString[i]);
505        }
506    }
507
508    strcpy(action, "getting and testing of binary type");
509    res = ures_getByKey(theBundle, "binarytest", res, &status);
510    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
511    CONFIRM_INT_EQ(ures_getType(res), URES_BINARY);
512    binResult=(uint8_t*)ures_getBinary(res,  &len, &status);
513    if(U_SUCCESS(status)){
514        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
515        CONFIRM_INT_EQ(len, 15);
516        for(i = 0; i<15; i++) {
517            CONFIRM_INT_EQ(binResult[i], i);
518        }
519    }
520
521    strcpy(action, "getting and testing of imported binary type");
522    res = ures_getByKey(theBundle, "importtest", res, &status);
523    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
524    CONFIRM_INT_EQ(ures_getType(res), URES_BINARY);
525    binResult=(uint8_t*)ures_getBinary(res,  &len, &status);
526    if(U_SUCCESS(status)){
527        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
528        CONFIRM_INT_EQ(len, 15);
529        for(i = 0; i<15; i++) {
530            CONFIRM_INT_EQ(binResult[i], i);
531        }
532    }
533
534    strcpy(action, "getting and testing of integer types");
535    res = ures_getByKey(theBundle, "one", res, &status);
536    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
537    CONFIRM_INT_EQ(ures_getType(res), URES_INT);
538    intResult=ures_getInt(res, &status);
539    uintResult = ures_getUInt(res, &status);
540    if(U_SUCCESS(status)){
541        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
542        CONFIRM_INT_EQ(uintResult, (uint32_t)intResult);
543        CONFIRM_INT_EQ(intResult, 1);
544    }
545
546    strcpy(action, "getting minusone");
547    res = ures_getByKey(theBundle, "minusone", res, &status);
548    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
549    CONFIRM_INT_EQ(ures_getType(res), URES_INT);
550    intResult=ures_getInt(res, &status);
551    uintResult = ures_getUInt(res, &status);
552    if(U_SUCCESS(status)){
553        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
554        CONFIRM_INT_EQ(uintResult, 0x0FFFFFFF); /* a 28 bit integer */
555        CONFIRM_INT_EQ(intResult, -1);
556        CONFIRM_INT_NE(uintResult, (uint32_t)intResult);
557    }
558
559    strcpy(action, "getting plusone");
560    res = ures_getByKey(theBundle, "plusone", res, &status);
561    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
562    CONFIRM_INT_EQ(ures_getType(res), URES_INT);
563    intResult=ures_getInt(res, &status);
564    uintResult = ures_getUInt(res, &status);
565    if(U_SUCCESS(status)){
566        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
567        CONFIRM_INT_EQ(uintResult, (uint32_t)intResult);
568        CONFIRM_INT_EQ(intResult, 1);
569    }
570
571    res = ures_getByKey(theBundle, "onehundredtwentythree", res, &status);
572    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
573    CONFIRM_INT_EQ(ures_getType(res), URES_INT);
574    intResult=ures_getInt(res, &status);
575    if(U_SUCCESS(status)){
576        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
577        CONFIRM_INT_EQ(intResult, 123);
578    }
579
580    /* this tests if escapes are preserved or not */
581    {
582        const UChar* str = tres_getString(theBundle,-1,"testescape",&len,&status);
583        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
584        if(U_SUCCESS(status)){
585            u_charsToUChars(expect,uExpect,(int32_t)strlen(expect)+1);
586            if(u_strcmp(uExpect,str)){
587                log_err("Did not get the expected string for testescape\n");
588            }
589        }
590    }
591    /* this tests if unescaping works are expected */
592    len=0;
593    {
594        char pattern[2048] = "";
595        int32_t patternLen;
596        UChar* expectedEscaped;
597        const UChar* got;
598        int32_t expectedLen;
599
600        /* This strcpy fixes compiler warnings about long strings */
601        strcpy(pattern, "[ \\\\u0020 \\\\u00A0 \\\\u1680 \\\\u2000 \\\\u2001 \\\\u2002 \\\\u2003 \\\\u2004 \\\\u2005 \\\\u2006 \\\\u2007 "
602            "\\\\u2008 \\\\u2009 \\\\u200A \\u200B \\\\u202F \\u205F \\\\u3000 \\u0000-\\u001F \\u007F \\u0080-\\u009F "
603            "\\\\u06DD \\\\u070F \\\\u180E \\\\u200C \\\\u200D \\\\u2028 \\\\u2029 \\\\u2060 \\\\u2061 \\\\u2062 \\\\u2063 "
604            "\\\\u206A-\\\\u206F \\\\uFEFF \\\\uFFF9-\\uFFFC \\U0001D173-\\U0001D17A \\U000F0000-\\U000FFFFD "
605            "\\U00100000-\\U0010FFFD \\uFDD0-\\uFDEF \\uFFFE-\\uFFFF \\U0001FFFE-\\U0001FFFF \\U0002FFFE-\\U0002FFFF "
606            );
607        strcat(pattern,
608            "\\U0003FFFE-\\U0003FFFF \\U0004FFFE-\\U0004FFFF \\U0005FFFE-\\U0005FFFF \\U0006FFFE-\\U0006FFFF "
609            "\\U0007FFFE-\\U0007FFFF \\U0008FFFE-\\U0008FFFF \\U0009FFFE-\\U0009FFFF \\U000AFFFE-\\U000AFFFF "
610            "\\U000BFFFE-\\U000BFFFF \\U000CFFFE-\\U000CFFFF \\U000DFFFE-\\U000DFFFF \\U000EFFFE-\\U000EFFFF "
611            "\\U000FFFFE-\\U000FFFFF \\U0010FFFE-\\U0010FFFF \\uD800-\\uDFFF \\\\uFFF9 \\\\uFFFA \\\\uFFFB "
612            "\\uFFFC \\uFFFD \\u2FF0-\\u2FFB \\u0340 \\u0341 \\\\u200E \\\\u200F \\\\u202A \\\\u202B \\\\u202C "
613            );
614        strcat(pattern,
615            "\\\\u202D \\\\u202E \\\\u206A \\\\u206B \\\\u206C \\\\u206D \\\\u206E \\\\u206F \\U000E0001 \\U000E0020-\\U000E007F "
616            "]"
617            );
618
619        patternLen = (int32_t)uprv_strlen(pattern);
620        expectedEscaped = (UChar*)malloc(U_SIZEOF_UCHAR * patternLen);
621        got = tres_getString(theBundle,-1,"test_unescaping",&len,&status);
622        expectedLen = u_unescape(pattern,expectedEscaped,patternLen);
623        if(got==NULL || u_strncmp(expectedEscaped,got,expectedLen)!=0 || expectedLen != len){
624            log_err("genrb failed to unescape string\n");
625        }
626        if(got != NULL){
627            for(i=0;i<expectedLen;i++){
628                if(expectedEscaped[i] != got[i]){
629                    log_verbose("Expected: 0x%04X Got: 0x%04X \n",expectedEscaped[i], got[i]);
630                }
631            }
632        }
633        free(expectedEscaped);
634        status = U_ZERO_ERROR;
635    }
636    /* test for jitterbug#1435 */
637    {
638        const UChar* str = tres_getString(theBundle,-1,"test_underscores",&len,&status);
639        expect ="test message ....";
640        u_charsToUChars(expect,uExpect,(int32_t)strlen(expect)+1);
641        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
642        if(str == NULL || u_strcmp(uExpect,str)){
643            log_err("Did not get the expected string for test_underscores.\n");
644        }
645    }
646    /* test for jitterbug#2626 */
647#if !UCONFIG_NO_COLLATION
648    {
649        UResourceBundle* resB = NULL;
650        const UChar* str  = NULL;
651        int32_t strLength = 0;
652        const UChar my[] = {0x0026,0x0027,0x0075,0x0027,0x0020,0x003d,0x0020,0x0027,0xff55,0x0027,0x0000}; /* &'\u0075' = '\uFF55' */
653        status = U_ZERO_ERROR;
654        resB = ures_getByKey(theBundle, "collations", resB, &status);
655        resB = ures_getByKey(resB, "standard", resB, &status);
656        str  = tres_getString(resB,-1,"Sequence",&strLength,&status);
657        if(!str || U_FAILURE(status)) {
658            log_data_err("Could not load collations from theBundle: %s\n", u_errorName(status));
659        } else if(u_strcmp(my,str) != 0){
660            log_err("Did not get the expected string for escaped \\u0075\n");
661        }
662        ures_close(resB);
663    }
664#endif
665    {
666        const char *sourcePath = ctest_dataSrcDir();
667        int32_t srcPathLen = (int32_t)strlen(sourcePath);
668        const char *deltaPath = ".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
669        int32_t deltaPathLen = (int32_t)strlen(deltaPath);
670        char *testDataFileName = (char *) malloc( srcPathLen+ deltaPathLen + 50 );
671        char *path = testDataFileName;
672
673        strcpy(path, sourcePath);
674        path += srcPathLen;
675        strcpy(path, deltaPath);
676        path += deltaPathLen;
677        status = U_ZERO_ERROR;
678        {
679            int32_t strLen =0;
680            const UChar* str = tres_getString(theBundle, -1, "testincludeUTF",&strLen,&status);
681            strcpy(path, "riwords.txt");
682            path[strlen("riwords.txt")]=0;
683            if(U_FAILURE(status)){
684                log_err("Could not get testincludeUTF resource from testtypes bundle. Error: %s\n",u_errorName(status));
685            }else{
686                /* open the file */
687                const char* cp = NULL;
688                UCHARBUF* ucbuf = ucbuf_open(testDataFileName,&cp,FALSE,FALSE,&status);
689                len = 0;
690                if(U_SUCCESS(status)){
691                    const UChar* buffer = ucbuf_getBuffer(ucbuf,&len,&status);
692                    if(U_SUCCESS(status)){
693                        /* verify the contents */
694                        if(strLen != len ){
695                            log_err("Did not get the expected len for riwords. Expected: %i , Got: %i\n", len ,strLen);
696                        }
697                        /* test string termination */
698                        if(u_strlen(str) != strLen || str[strLen]!= 0 ){
699                            log_err("testinclude not null terminated!\n");
700                        }
701                        if(u_strncmp(str, buffer,strLen)!=0){
702                            log_err("Did not get the expected string from riwords. Include functionality failed for genrb.\n");
703                        }
704                    }else{
705                        log_err("ucbuf failed to open %s. Error: %s\n", testDataFileName, u_errorName(status));
706                    }
707
708                    ucbuf_close(ucbuf);
709                }else{
710                    log_err("Could not get riwords.txt (path : %s). Error: %s\n",testDataFileName,u_errorName(status));
711                }
712            }
713        }
714        status = U_ZERO_ERROR;
715        {
716            int32_t strLen =0;
717            const UChar* str = tres_getString(theBundle, -1, "testinclude",&strLen,&status);
718            strcpy(path, "translit_rules.txt");
719            path[strlen("translit_rules.txt")]=0;
720
721            if(U_FAILURE(status)){
722                log_err("Could not get testinclude resource from testtypes bundle. Error: %s\n",u_errorName(status));
723            }else{
724                /* open the file */
725                const char* cp=NULL;
726                UCHARBUF* ucbuf = ucbuf_open(testDataFileName,&cp,FALSE,FALSE,&status);
727                len = 0;
728                if(U_SUCCESS(status)){
729                    const UChar* buffer = ucbuf_getBuffer(ucbuf,&len,&status);
730                    if(U_SUCCESS(status)){
731                        /* verify the contents */
732                        if(strLen != len ){
733                            log_err("Did not get the expected len for translit_rules. Expected: %i , Got: %i\n", len ,strLen);
734                        }
735                        if(u_strncmp(str, buffer,strLen)!=0){
736                            log_err("Did not get the expected string from translit_rules. Include functionality failed for genrb.\n");
737                        }
738                    }else{
739                        log_err("ucbuf failed to open %s. Error: %s\n", testDataFileName, u_errorName(status));
740                    }
741                    ucbuf_close(ucbuf);
742                }else{
743                    log_err("Could not get translit_rules.txt (path : %s). Error: %s\n",testDataFileName,u_errorName(status));
744                }
745            }
746        }
747        free(testDataFileName);
748    }
749    ures_close(res);
750    ures_close(theBundle);
751
752}
753
754static void TestEmptyTypes() {
755    UResourceBundle* theBundle = NULL;
756    char action[256];
757    const char* testdatapath;
758    UErrorCode status = U_ZERO_ERROR;
759    UResourceBundle* res = NULL;
760    UResourceBundle* resArray = NULL;
761    const uint8_t *binResult = NULL;
762    int32_t len = 0;
763    int32_t intResult = 0;
764    const UChar *zeroString;
765    const int32_t *zeroIntVect = NULL;
766
767    strcpy(action, "Construction of testtypes bundle");
768    testdatapath=loadTestData(&status);
769    if(U_FAILURE(status))
770    {
771        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
772        return;
773    }
774
775    theBundle = ures_open(testdatapath, "testtypes", &status);
776
777    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
778
779    CONFIRM_INT_NE(theBundle, NULL);
780
781    /* This test reads the string "abc\u0000def" from the bundle   */
782    /* if everything is working correctly, the size of this string */
783    /* should be 7. Everything else is a wrong answer, esp. 3 and 6*/
784
785    status = U_ZERO_ERROR;
786    strcpy(action, "getting and testing of explicit string of zero length string");
787    res = ures_getByKey(theBundle, "emptyexplicitstring", res, &status);
788    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
789    CONFIRM_INT_EQ(ures_getType(res), URES_STRING);
790    zeroString=tres_getString(res, -1, NULL, &len, &status);
791    if(U_SUCCESS(status)){
792        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
793        CONFIRM_INT_EQ(len, 0);
794        CONFIRM_INT_EQ(u_strlen(zeroString), 0);
795    }
796    else {
797        log_err("Couldn't get emptyexplicitstring\n");
798    }
799
800    status = U_ZERO_ERROR;
801    strcpy(action, "getting and testing of normal string of zero length string");
802    res = ures_getByKey(theBundle, "emptystring", res, &status);
803    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
804    CONFIRM_INT_EQ(ures_getType(res), URES_STRING);
805    zeroString=tres_getString(res, -1, NULL, &len, &status);
806    if(U_SUCCESS(status)){
807        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
808        CONFIRM_INT_EQ(len, 0);
809        CONFIRM_INT_EQ(u_strlen(zeroString), 0);
810    }
811    else {
812        log_err("Couldn't get emptystring\n");
813    }
814
815    status = U_ZERO_ERROR;
816    strcpy(action, "getting and testing of empty int");
817    res = ures_getByKey(theBundle, "emptyint", res, &status);
818    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
819    CONFIRM_INT_EQ(ures_getType(res), URES_INT);
820    intResult=ures_getInt(res, &status);
821    if(U_SUCCESS(status)){
822        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
823        CONFIRM_INT_EQ(intResult, 0);
824    }
825    else {
826        log_err("Couldn't get emptystring\n");
827    }
828
829    status = U_ZERO_ERROR;
830    strcpy(action, "getting and testing of zero length intvector");
831    res = ures_getByKey(theBundle, "emptyintv", res, &status);
832    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
833    CONFIRM_INT_EQ(ures_getType(res), URES_INT_VECTOR);
834
835    if(U_FAILURE(status)){
836        log_err("Couldn't get emptyintv key %s\n", u_errorName(status));
837    }
838    else {
839        zeroIntVect=ures_getIntVector(res, &len, &status);
840        (void)zeroIntVect;    /* Suppress set but not used warning. */
841        if(!U_SUCCESS(status) || resArray != NULL || len != 0) {
842            log_err("Shouldn't get emptyintv\n");
843        }
844    }
845
846    status = U_ZERO_ERROR;
847    strcpy(action, "getting and testing of zero length emptybin");
848    res = ures_getByKey(theBundle, "emptybin", res, &status);
849    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
850    CONFIRM_INT_EQ(ures_getType(res), URES_BINARY);
851
852    if(U_FAILURE(status)){
853        log_err("Couldn't get emptybin key %s\n", u_errorName(status));
854    }
855    else {
856        binResult=ures_getBinary(res, &len, &status);
857        (void)binResult;      /* Suppress set but not used warning. */
858        if(!U_SUCCESS(status) || len != 0) {
859            log_err("Couldn't get emptybin, or it's not empty\n");
860        }
861    }
862
863    status = U_ZERO_ERROR;
864    strcpy(action, "getting and testing of zero length emptyarray");
865    res = ures_getByKey(theBundle, "emptyarray", res, &status);
866    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
867    CONFIRM_INT_EQ(ures_getType(res), URES_ARRAY);
868
869    if(U_FAILURE(status)){
870        log_err("Couldn't get emptyarray key %s\n", u_errorName(status));
871    }
872    else {
873        resArray=ures_getByIndex(res, 0, resArray, &status);
874        if(U_SUCCESS(status) || resArray != NULL){
875            log_err("Shouldn't get emptyarray[0]\n");
876        }
877    }
878
879    status = U_ZERO_ERROR;
880    strcpy(action, "getting and testing of zero length emptytable");
881    res = ures_getByKey(theBundle, "emptytable", res, &status);
882    CONFIRM_ErrorCode(status, U_ZERO_ERROR);
883    CONFIRM_INT_EQ(ures_getType(res), URES_TABLE);
884
885    if(U_FAILURE(status)){
886        log_err("Couldn't get emptytable key %s\n", u_errorName(status));
887    }
888    else {
889        resArray=ures_getByIndex(res, 0, resArray, &status);
890        if(U_SUCCESS(status) || resArray != NULL){
891            log_err("Shouldn't get emptytable[0]\n");
892        }
893    }
894
895    ures_close(res);
896    ures_close(theBundle);
897}
898
899static void TestEmptyBundle(){
900    UErrorCode status = U_ZERO_ERROR;
901    const char* testdatapath=NULL;
902    UResourceBundle *resb=0, *dResB=0;
903
904    testdatapath=loadTestData(&status);
905    if(U_FAILURE(status))
906    {
907        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
908        return;
909    }
910    resb = ures_open(testdatapath, "testempty", &status);
911
912    if(U_SUCCESS(status)){
913        dResB =  ures_getByKey(resb,"test",dResB,&status);
914        if(status!= U_MISSING_RESOURCE_ERROR){
915            log_err("Did not get the expected error from an empty resource bundle. Expected : %s Got: %s\n",
916                u_errorName(U_MISSING_RESOURCE_ERROR),u_errorName(status));
917        }
918    }
919    ures_close(dResB);
920    ures_close(resb);
921}
922
923static void TestBinaryCollationData(){
924#if !UCONFIG_NO_COLLATION
925    UErrorCode status=U_ZERO_ERROR;
926    const char*      locale="te";
927    const char* testdatapath;
928    UResourceBundle *teRes = NULL;
929    UResourceBundle *coll=NULL;
930    UResourceBundle *binColl = NULL;
931    uint8_t *binResult = NULL;
932    int32_t len=0;
933    const char* action="testing the binary collaton data";
934
935    log_verbose("Testing binary collation data resource......\n");
936
937    testdatapath=loadTestData(&status);
938    if(U_FAILURE(status))
939    {
940        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
941        return;
942    }
943
944
945    teRes=ures_open(testdatapath, locale, &status);
946    if(U_FAILURE(status)){
947        log_err("ERROR: Failed to get resource for \"te\" with %s", myErrorName(status));
948        return;
949    }
950    status=U_ZERO_ERROR;
951    coll = ures_getByKey(teRes, "collations", coll, &status);
952    coll = ures_getByKey(coll, "standard", coll, &status);
953    if(U_SUCCESS(status)){
954        CONFIRM_ErrorCode(status, U_ZERO_ERROR);
955        CONFIRM_INT_EQ(ures_getType(coll), URES_TABLE);
956        binColl=ures_getByKey(coll, "%%CollationBin", binColl, &status);
957        if(U_SUCCESS(status)){
958            CONFIRM_ErrorCode(status, U_ZERO_ERROR);
959            CONFIRM_INT_EQ(ures_getType(binColl), URES_BINARY);
960            binResult=(uint8_t*)ures_getBinary(binColl,  &len, &status);
961            (void)binResult;    /* Suppress set but not used warning. */
962            if(U_SUCCESS(status)){
963                CONFIRM_ErrorCode(status, U_ZERO_ERROR);
964                CONFIRM_INT_GE(len, 1);
965            }
966
967        }else{
968            log_err("ERROR: ures_getByKey(locale(te), %%CollationBin) failed\n");
969        }
970    }
971    else{
972        log_err("ERROR: ures_getByKey(locale(te), collations) failed\n");
973        return;
974    }
975    ures_close(binColl);
976    ures_close(coll);
977    ures_close(teRes);
978#endif
979}
980
981static void TestAPI() {
982    UErrorCode status=U_ZERO_ERROR;
983    int32_t len=0;
984    const char* key=NULL;
985    const UChar* value=NULL;
986    const char* testdatapath;
987    UChar* utestdatapath=NULL;
988    char convOutput[256];
989    UChar largeBuffer[1025];
990    UResourceBundle *teRes = NULL;
991    UResourceBundle *teFillin=NULL;
992    UResourceBundle *teFillin2=NULL;
993
994    log_verbose("Testing ures_openU()......\n");
995
996    testdatapath=loadTestData(&status);
997    if(U_FAILURE(status))
998    {
999        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
1000        return;
1001    }
1002    len =(int32_t)strlen(testdatapath);
1003    utestdatapath = (UChar*) malloc((len+10)*sizeof(UChar));
1004
1005    u_charsToUChars(testdatapath, utestdatapath, (int32_t)strlen(testdatapath)+1);
1006#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) && U_FILE_SEP_CHAR == '\\'
1007    {
1008        /* Convert all backslashes to forward slashes so that we can make sure that ures_openU
1009           can handle invariant characters. */
1010        UChar *backslash;
1011        while ((backslash = u_strchr(utestdatapath, 0x005C))) {
1012            *backslash = 0x002F;
1013        }
1014    }
1015#endif
1016
1017    u_memset(largeBuffer, 0x0030, UPRV_LENGTHOF(largeBuffer));
1018    largeBuffer[UPRV_LENGTHOF(largeBuffer)-1] = 0;
1019
1020    /*Test ures_openU */
1021
1022    status = U_ZERO_ERROR;
1023    ures_close(ures_openU(largeBuffer, "root", &status));
1024    if(status != U_ILLEGAL_ARGUMENT_ERROR){
1025        log_err("ERROR: ures_openU() worked when the path is very large. It returned %s\n", myErrorName(status));
1026    }
1027
1028    status = U_ZERO_ERROR;
1029    ures_close(ures_openU(NULL, "root", &status));
1030    if(U_FAILURE(status)){
1031        log_err_status(status, "ERROR: ures_openU() failed path = NULL with %s\n", myErrorName(status));
1032    }
1033
1034    status = U_ILLEGAL_ARGUMENT_ERROR;
1035    if(ures_openU(NULL, "root", &status) != NULL){
1036        log_err("ERROR: ures_openU() worked with error status with %s\n", myErrorName(status));
1037    }
1038
1039    status = U_ZERO_ERROR;
1040    teRes=ures_openU(utestdatapath, "te", &status);
1041    if(U_FAILURE(status)){
1042        log_err_status(status, "ERROR: ures_openU() failed path =%s with %s\n", austrdup(utestdatapath), myErrorName(status));
1043        return;
1044    }
1045    /*Test ures_getLocale() */
1046    log_verbose("Testing ures_getLocale() .....\n");
1047    if(strcmp(ures_getLocale(teRes, &status), "te") != 0){
1048        log_err("ERROR: ures_getLocale() failed. Expected = te_TE Got = %s\n", ures_getLocale(teRes, &status));
1049    }
1050    /*Test ures_getNextString() */
1051    teFillin=ures_getByKey(teRes, "tagged_array_in_te_te_IN", teFillin, &status);
1052    key=ures_getKey(teFillin);
1053    value=(UChar*)ures_getNextString(teFillin, &len, &key, &status);
1054    (void)value;    /* Suppress set but not used warning. */
1055    ures_resetIterator(NULL);
1056    value=(UChar*)ures_getNextString(teFillin, &len, &key, &status);
1057    if(status !=U_INDEX_OUTOFBOUNDS_ERROR){
1058        log_err("ERROR: calling getNextString where index out of bounds should return U_INDEX_OUTOFBOUNDS_ERROR, Got : %s\n",
1059                       myErrorName(status));
1060    }
1061    ures_resetIterator(teRes);
1062    /*Test ures_getNextResource() where resource is table*/
1063    status=U_ZERO_ERROR;
1064#if (U_CHARSET_FAMILY == U_ASCII_FAMILY)
1065    /* The next key varies depending on the charset. */
1066    teFillin=ures_getNextResource(teRes, teFillin, &status);
1067    if(U_FAILURE(status)){
1068        log_err("ERROR: ures_getNextResource() failed \n");
1069    }
1070    key=ures_getKey(teFillin);
1071    /*if(strcmp(key, "%%CollationBin") != 0){*/
1072    /*if(strcmp(key, "array_2d_in_Root_te") != 0){*/ /* added "aliasClient" that goes first */
1073    if(strcmp(key, "a") != 0){
1074        log_err("ERROR: ures_getNextResource() failed\n");
1075    }
1076#endif
1077
1078    /*Test ures_getByIndex on string Resource*/
1079    teFillin=ures_getByKey(teRes, "string_only_in_te", teFillin, &status);
1080    teFillin2=ures_getByIndex(teFillin, 0, teFillin2, &status);
1081    if(U_FAILURE(status)){
1082        log_err("ERROR: ures_getByIndex on string resource failed\n");
1083    }
1084    if(strcmp(u_austrcpy(convOutput, tres_getString(teFillin2, -1, NULL, &len, &status)), "TE") != 0){
1085        status=U_ZERO_ERROR;
1086        log_err("ERROR: ures_getByIndex on string resource fetched the key=%s, expected \"TE\" \n", austrdup(ures_getString(teFillin2, &len, &status)));
1087    }
1088
1089    /*ures_close(teRes);*/
1090
1091    /*Test ures_openFillIn*/
1092    log_verbose("Testing ures_openFillIn......\n");
1093    status=U_ZERO_ERROR;
1094    ures_openFillIn(teRes, testdatapath, "te", &status);
1095    if(U_FAILURE(status)){
1096        log_err("ERROR: ures_openFillIn failed\n");
1097        return;
1098    }
1099    if(strcmp(ures_getLocale(teRes, &status), "te") != 0){
1100        log_err("ERROR: ures_openFillIn did not open the ResourceBundle correctly\n");
1101    }
1102    ures_getByKey(teRes, "string_only_in_te", teFillin, &status);
1103    teFillin2=ures_getNextResource(teFillin, teFillin2, &status);
1104    if(ures_getType(teFillin2) != URES_STRING){
1105        log_err("ERROR: getType for getNextResource after ures_openFillIn failed\n");
1106    }
1107    teFillin2=ures_getNextResource(teFillin, teFillin2, &status);
1108    if(status !=U_INDEX_OUTOFBOUNDS_ERROR){
1109        log_err("ERROR: calling getNextResource where index out of bounds should return U_INDEX_OUTOFBOUNDS_ERROR, Got : %s\n",
1110                       myErrorName(status));
1111    }
1112
1113    ures_close(teFillin);
1114    ures_close(teFillin2);
1115    ures_close(teRes);
1116
1117    /* Test that ures_getLocale() returns the "real" locale ID */
1118    status=U_ZERO_ERROR;
1119    teRes=ures_open(NULL, "dE_At_NOWHERE_TO_BE_FOUND", &status);
1120    if(U_FAILURE(status)) {
1121        log_data_err("unable to open a locale resource bundle from \"dE_At_NOWHERE_TO_BE_FOUND\"(%s)\n", u_errorName(status));
1122    } else {
1123        if(0!=strcmp("de_AT", ures_getLocale(teRes, &status))) {
1124            log_data_err("ures_getLocale(\"dE_At_NOWHERE_TO_BE_FOUND\")=%s but must be de_AT\n", ures_getLocale(teRes, &status));
1125        }
1126        ures_close(teRes);
1127    }
1128
1129    /* same test, but with an aliased locale resource bundle */
1130    status=U_ZERO_ERROR;
1131    teRes=ures_open(NULL, "iW_Il_depRecaTed_HebreW", &status);
1132    if(U_FAILURE(status)) {
1133        log_data_err("unable to open a locale resource bundle from \"iW_Il_depRecaTed_HebreW\"(%s)\n", u_errorName(status));
1134    } else {
1135        if(0!=strcmp("he_IL", ures_getLocale(teRes, &status))) {
1136            log_data_err("ures_getLocale(\"iW_Il_depRecaTed_HebreW\")=%s but must be he_IL\n", ures_getLocale(teRes, &status));
1137        }
1138        ures_close(teRes);
1139    }
1140    free(utestdatapath);
1141}
1142
1143static void TestErrorConditions(){
1144    UErrorCode status=U_ZERO_ERROR;
1145    const char *key=NULL;
1146    const UChar *value=NULL;
1147    const char* testdatapath;
1148    UChar* utestdatapath;
1149    int32_t len=0;
1150    UResourceBundle *teRes = NULL;
1151    UResourceBundle *coll=NULL;
1152    UResourceBundle *binColl = NULL;
1153    UResourceBundle *teFillin=NULL;
1154    UResourceBundle *teFillin2=NULL;
1155    uint8_t *binResult = NULL;
1156    int32_t resultLen;
1157
1158
1159    testdatapath = loadTestData(&status);
1160    if(U_FAILURE(status))
1161    {
1162        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
1163        return;
1164    }
1165    len = (int32_t)strlen(testdatapath);
1166    utestdatapath = (UChar*) malloc(sizeof(UChar) *(len+10));
1167    u_uastrcpy(utestdatapath, testdatapath);
1168
1169    /*Test ures_openU with status != U_ZERO_ERROR*/
1170    log_verbose("Testing ures_openU() with status != U_ZERO_ERROR.....\n");
1171    status=U_ILLEGAL_ARGUMENT_ERROR;
1172    teRes=ures_openU(utestdatapath, "te", &status);
1173    if(U_FAILURE(status)){
1174        log_verbose("ures_openU() failed as expected path =%s with status != U_ZERO_ERROR\n", testdatapath);
1175    }else{
1176        log_err("ERROR: ures_openU() is supposed to fail path =%s with status != U_ZERO_ERROR\n", austrdup(utestdatapath));
1177        ures_close(teRes);
1178    }
1179    /*Test ures_openFillIn with UResourceBundle = NULL*/
1180    log_verbose("Testing ures_openFillIn with UResourceBundle = NULL.....\n");
1181    status=U_ZERO_ERROR;
1182    ures_openFillIn(NULL, testdatapath, "te", &status);
1183    if(status != U_ILLEGAL_ARGUMENT_ERROR){
1184        log_err("ERROR: ures_openFillIn with UResourceBundle= NULL should fail.  Expected U_ILLEGAL_ARGUMENT_ERROR, Got: %s\n",
1185                        myErrorName(status));
1186    }
1187    /*Test ures_getLocale() with status != U_ZERO_ERROR*/
1188    status=U_ZERO_ERROR;
1189    teRes=ures_openU(utestdatapath, "te", &status);
1190    if(U_FAILURE(status)){
1191        log_err("ERROR: ures_openU() failed path =%s with %s\n", austrdup(utestdatapath), myErrorName(status));
1192        return;
1193    }
1194    status=U_ILLEGAL_ARGUMENT_ERROR;
1195    if(ures_getLocale(teRes, &status) != NULL){
1196        log_err("ERROR: ures_getLocale is supposed to fail with errorCode != U_ZERO_ERROR\n");
1197    }
1198    /*Test ures_getLocale() with UResourceBundle = NULL*/
1199    status=U_ZERO_ERROR;
1200    if(ures_getLocale(NULL, &status) != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1201        log_err("ERROR: ures_getLocale is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1202                                           myErrorName(status));
1203    }
1204    /*Test ures_getSize() with UResourceBundle = NULL */
1205    status=U_ZERO_ERROR;
1206    if(ures_getSize(NULL) != 0){
1207        log_err("ERROR: ures_getSize() should return 0 when UResourceBundle=NULL.  Got =%d\n", ures_getSize(NULL));
1208    }
1209    /*Test ures_getType() with UResourceBundle = NULL should return URES_NONE==-1*/
1210    status=U_ZERO_ERROR;
1211    if(ures_getType(NULL) != URES_NONE){
1212        log_err("ERROR: ures_getType() should return URES_NONE when UResourceBundle=NULL.  Got =%d\n", ures_getType(NULL));
1213    }
1214    /*Test ures_getKey() with UResourceBundle = NULL*/
1215    status=U_ZERO_ERROR;
1216    if(ures_getKey(NULL) != NULL){
1217        log_err("ERROR: ures_getKey() should return NULL when UResourceBundle=NULL.  Got =%d\n", ures_getKey(NULL));
1218    }
1219    /*Test ures_hasNext() with UResourceBundle = NULL*/
1220    status=U_ZERO_ERROR;
1221    if(ures_hasNext(NULL) != FALSE){
1222        log_err("ERROR: ures_hasNext() should return FALSE when UResourceBundle=NULL.  Got =%d\n", ures_hasNext(NULL));
1223    }
1224    /*Test ures_get() with UResourceBundle = NULL*/
1225    status=U_ZERO_ERROR;
1226    if(ures_getStringByKey(NULL, "string_only_in_te", &resultLen, &status) != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1227        log_err("ERROR: ures_get is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1228                                           myErrorName(status));
1229    }
1230    /*Test ures_getByKey() with UResourceBundle = NULL*/
1231    status=U_ZERO_ERROR;
1232    teFillin=ures_getByKey(NULL, "string_only_in_te", teFillin, &status);
1233    if( teFillin != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1234        log_err("ERROR: ures_getByKey is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1235                                           myErrorName(status));
1236    }
1237    /*Test ures_getByKey() with status != U_ZERO_ERROR*/
1238    teFillin=ures_getByKey(NULL, "string_only_in_te", teFillin, &status);
1239    if(teFillin != NULL ){
1240        log_err("ERROR: ures_getByKey is supposed to fail when errorCode != U_ZERO_ERROR\n");
1241    }
1242    /*Test ures_getStringByKey() with UResourceBundle = NULL*/
1243    status=U_ZERO_ERROR;
1244    if(ures_getStringByKey(NULL, "string_only_in_te", &len, &status) != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1245        log_err("ERROR: ures_getStringByKey is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1246                                           myErrorName(status));
1247    }
1248    /*Test ures_getStringByKey() with status != U_ZERO_ERROR*/
1249    if(ures_getStringByKey(teRes, "string_only_in_te", &len, &status) != NULL){
1250        log_err("ERROR: ures_getStringByKey is supposed to fail when status != U_ZERO_ERROR. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1251                                           myErrorName(status));
1252    }
1253    /*Test ures_getString() with UResourceBundle = NULL*/
1254    status=U_ZERO_ERROR;
1255    if(ures_getString(NULL, &len, &status) != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1256        log_err("ERROR: ures_getString is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1257                                           myErrorName(status));
1258    }
1259    /*Test ures_getString() with status != U_ZERO_ERROR*/
1260    if(ures_getString(teRes, &len, &status) != NULL){
1261        log_err("ERROR: ures_getString is supposed to fail when status != U_ZERO_ERROR. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1262                                           myErrorName(status));
1263    }
1264    /*Test ures_getBinary() with UResourceBundle = NULL*/
1265    status=U_ZERO_ERROR;
1266    if(ures_getBinary(NULL, &len, &status) != NULL && status != U_ILLEGAL_ARGUMENT_ERROR){
1267        log_err("ERROR: ures_getBinary is supposed to fail when UResourceBundle = NULL. Expected: errorCode = U_ILLEGAL_ARGUMENT_ERROR, Got: errorCode=%s\n",
1268                                           myErrorName(status));
1269    }
1270    /*Test ures_getBinary(0 status != U_ILLEGAL_ARGUMENT_ERROR*/
1271    status=U_ZERO_ERROR;
1272    coll = ures_getByKey(teRes, "collations", coll, &status);
1273    coll = ures_getByKey(teRes, "standard", coll, &status);
1274    binColl=ures_getByKey(coll, "%%CollationBin", binColl, &status);
1275
1276    status=U_ILLEGAL_ARGUMENT_ERROR;
1277    binResult=(uint8_t*)ures_getBinary(binColl,  &len, &status);
1278    if(binResult != NULL){
1279        log_err("ERROR: ures_getBinary() with status != U_ZERO_ERROR is supposed to fail\n");
1280    }
1281
1282    /*Test ures_getNextResource() with status != U_ZERO_ERROR*/
1283    teFillin=ures_getNextResource(teRes, teFillin, &status);
1284    if(teFillin != NULL){
1285        log_err("ERROR: ures_getNextResource() with errorCode != U_ZERO_ERROR is supposed to fail\n");
1286    }
1287    /*Test ures_getNextResource() with UResourceBundle = NULL*/
1288    status=U_ZERO_ERROR;
1289    teFillin=ures_getNextResource(NULL, teFillin, &status);
1290    if(teFillin != NULL || status != U_ILLEGAL_ARGUMENT_ERROR){
1291        log_err("ERROR: ures_getNextResource() with UResourceBundle = NULL is supposed to fail.  Expected : U_IILEGAL_ARGUMENT_ERROR, Got : %s\n",
1292                                          myErrorName(status));
1293    }
1294    /*Test ures_getNextString with errorCode != U_ZERO_ERROR*/
1295    teFillin=ures_getByKey(teRes, "tagged_array_in_te_te_IN", teFillin, &status);
1296    key=ures_getKey(teFillin);
1297    status = U_ILLEGAL_ARGUMENT_ERROR;
1298    value=(UChar*)ures_getNextString(teFillin, &len, &key, &status);
1299    if(value != NULL){
1300        log_err("ERROR: ures_getNextString() with errorCode != U_ZERO_ERROR is supposed to fail\n");
1301    }
1302    /*Test ures_getNextString with UResourceBundle = NULL*/
1303    status=U_ZERO_ERROR;
1304    value=(UChar*)ures_getNextString(NULL, &len, &key, &status);
1305    if(value != NULL || status != U_ILLEGAL_ARGUMENT_ERROR){
1306        log_err("ERROR: ures_getNextString() with UResourceBundle=NULL is supposed to fail\n Expected: U_ILLEGAL_ARGUMENT_ERROR, Got: %s\n",
1307                                    myErrorName(status));
1308    }
1309    /*Test ures_getByIndex with errorCode != U_ZERO_ERROR*/
1310    status=U_ZERO_ERROR;
1311    teFillin=ures_getByKey(teRes, "array_only_in_te", teFillin, &status);
1312    if(ures_countArrayItems(teRes, "array_only_in_te", &status) != 4) {
1313      log_err("ERROR: Wrong number of items in an array!\n");
1314    }
1315    status=U_ILLEGAL_ARGUMENT_ERROR;
1316    teFillin2=ures_getByIndex(teFillin, 0, teFillin2, &status);
1317    if(teFillin2 != NULL){
1318        log_err("ERROR: ures_getByIndex() with errorCode != U_ZERO_ERROR is supposed to fail\n");
1319    }
1320    /*Test ures_getByIndex with UResourceBundle = NULL */
1321    status=U_ZERO_ERROR;
1322    teFillin2=ures_getByIndex(NULL, 0, teFillin2, &status);
1323    if(status != U_ILLEGAL_ARGUMENT_ERROR){
1324        log_err("ERROR: ures_getByIndex() with UResourceBundle=NULL is supposed to fail\n Expected: U_ILLEGAL_ARGUMENT_ERROR, Got: %s\n",
1325                                    myErrorName(status));
1326    }
1327    /*Test ures_getStringByIndex with errorCode != U_ZERO_ERROR*/
1328    status=U_ZERO_ERROR;
1329    teFillin=ures_getByKey(teRes, "array_only_in_te", teFillin, &status);
1330    status=U_ILLEGAL_ARGUMENT_ERROR;
1331    value=(UChar*)ures_getStringByIndex(teFillin, 0, &len, &status);
1332    if( value != NULL){
1333        log_err("ERROR: ures_getSringByIndex() with errorCode != U_ZERO_ERROR is supposed to fail\n");
1334    }
1335    /*Test ures_getStringByIndex with UResourceBundle = NULL */
1336    status=U_ZERO_ERROR;
1337    value=(UChar*)ures_getStringByIndex(NULL, 0, &len, &status);
1338    if(value != NULL || status != U_ILLEGAL_ARGUMENT_ERROR){
1339        log_err("ERROR: ures_getStringByIndex() with UResourceBundle=NULL is supposed to fail\n Expected: U_ILLEGAL_ARGUMENT_ERROR, Got: %s\n",
1340                                    myErrorName(status));
1341    }
1342    /*Test ures_getStringByIndex with UResourceBundle = NULL */
1343    status=U_ZERO_ERROR;
1344    value=(UChar*)ures_getStringByIndex(teFillin, 9999, &len, &status);
1345    if(value != NULL || status != U_MISSING_RESOURCE_ERROR){
1346        log_err("ERROR: ures_getStringByIndex() with index that is too big is supposed to fail\n Expected: U_MISSING_RESOURCE_ERROR, Got: %s\n",
1347                                    myErrorName(status));
1348    }
1349    /*Test ures_getInt() where UResourceBundle = NULL */
1350    status=U_ZERO_ERROR;
1351    if(ures_getInt(NULL, &status) != -1 && status != U_ILLEGAL_ARGUMENT_ERROR){
1352        log_err("ERROR: ures_getInt() with UResourceBundle = NULL should fail. Expected: U_IILEGAL_ARGUMENT_ERROR, Got: %s\n",
1353                           myErrorName(status));
1354    }
1355    /*Test ures_getInt() where status != U_ZERO_ERROR */
1356    if(ures_getInt(teRes, &status) != -1){
1357        log_err("ERROR: ures_getInt() with errorCode != U_ZERO_ERROR should fail\n");
1358    }
1359
1360    ures_close(teFillin);
1361    ures_close(teFillin2);
1362    ures_close(coll);
1363    ures_close(binColl);
1364    ures_close(teRes);
1365    free(utestdatapath);
1366
1367
1368}
1369
1370static void TestGetVersion(){
1371    UVersionInfo minVersionArray = {0x01, 0x00, 0x00, 0x00};
1372    UVersionInfo maxVersionArray = {0x50, 0xff, 0xcf, 0xcf};
1373    UVersionInfo versionArray;
1374    UErrorCode status= U_ZERO_ERROR;
1375    UResourceBundle* resB = NULL;
1376    int i=0, j = 0;
1377    int locCount = uloc_countAvailable();
1378    const char *locName = "root";
1379
1380    log_verbose("The ures_getVersion tests begin : \n");
1381
1382    for(j = -1; j < locCount; j++) {
1383        if(j >= 0) {
1384            locName = uloc_getAvailable(j);
1385        }
1386        log_verbose("Testing version number for locale %s\n", locName);
1387        resB = ures_open(NULL,locName, &status);
1388        if (U_FAILURE(status)) {
1389            log_err_status(status, "Resource bundle creation for locale %s failed.: %s\n", locName, myErrorName(status));
1390            ures_close(resB);
1391            return;
1392        }
1393        ures_getVersion(resB, versionArray);
1394        for (i=0; i<4; ++i) {
1395            if (versionArray[i] < minVersionArray[i] ||
1396                versionArray[i] > maxVersionArray[i])
1397            {
1398                log_err("Testing ures_getVersion(%-5s) - unexpected result: %d.%d.%d.%d\n",
1399                    locName, versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
1400                break;
1401            }
1402        }
1403        ures_close(resB);
1404    }
1405}
1406
1407
1408static void TestGetVersionColl(){
1409#if !UCONFIG_NO_COLLATION
1410    UVersionInfo minVersionArray = {0x00, 0x00, 0x00, 0x00};
1411    UVersionInfo maxVersionArray = {0x50, 0x80, 0xcf, 0xcf};
1412    UVersionInfo versionArray;
1413    UErrorCode status= U_ZERO_ERROR;
1414    UResourceBundle* resB = NULL;
1415    UEnumeration *locs= NULL;
1416    int i=0;
1417    const char *locName = "root";
1418    int32_t locLen;
1419    const UChar* rules =NULL;
1420    int32_t len = 0;
1421
1422    /* test NUL termination of UCARules */
1423    resB = ures_open(U_ICUDATA_COLL,locName, &status);
1424    rules = tres_getString(resB,-1,"UCARules",&len, &status);
1425    if(!rules || U_FAILURE(status)) {
1426        log_data_err("Could not load UCARules for locale %s\n", locName);
1427        status = U_ZERO_ERROR;
1428    } else if(u_strlen(rules) != len){
1429        log_err("UCARules string not nul terminated! \n");
1430    }
1431    ures_close(resB);
1432
1433    log_verbose("The ures_getVersion(%s) tests begin : \n", U_ICUDATA_COLL);
1434    locs = ures_openAvailableLocales(U_ICUDATA_COLL, &status);
1435    if (U_FAILURE(status)) {
1436       log_err_status(status, "enumeration of %s failed.: %s\n", U_ICUDATA_COLL, myErrorName(status));
1437       return;
1438    }
1439
1440    for (;;) {
1441        log_verbose("Testing version number for locale %s\n", locName);
1442        resB = ures_open(U_ICUDATA_COLL,locName, &status);
1443        if (U_FAILURE(status)) {
1444            log_err("Resource bundle creation for locale %s:%s failed.: %s\n", U_ICUDATA_COLL, locName, myErrorName(status));
1445            ures_close(resB);
1446            break;
1447        }
1448        ures_getVersion(resB, versionArray);
1449        for (i=0; i<4; ++i) {
1450            if (versionArray[i] < minVersionArray[i] ||
1451                versionArray[i] > maxVersionArray[i])
1452            {
1453                log_err("Testing ures_getVersion(%-5s) - unexpected result: %d.%d.%d.%d\n",
1454                    locName, versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
1455                break;
1456            }
1457        }
1458        ures_close(resB);
1459        locName = uenum_next(locs, &locLen, &status);
1460        if(U_FAILURE(status)) {
1461            log_err("uenum_next(locs) error %s\n", u_errorName(status));
1462            break;
1463        }
1464        if(locName == NULL) {
1465            break;
1466        }
1467    }
1468    uenum_close(locs);
1469#endif  /* !UCONFIG_NO_COLLATION */
1470}
1471
1472static void TestResourceBundles()
1473{
1474    UErrorCode status = U_ZERO_ERROR;
1475    loadTestData(&status);
1476    if(U_FAILURE(status)) {
1477        log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
1478        return;
1479    }
1480
1481    testTag("only_in_Root", TRUE, FALSE, FALSE);
1482    testTag("in_Root_te", TRUE, TRUE, FALSE);
1483    testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
1484    testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
1485    testTag("only_in_te", FALSE, TRUE, FALSE);
1486    testTag("only_in_te_IN", FALSE, FALSE, TRUE);
1487    testTag("in_te_te_IN", FALSE, TRUE, TRUE);
1488    testTag("nonexistent", FALSE, FALSE, FALSE);
1489
1490    log_verbose("Passed:=  %d   Failed=   %d \n", pass, fail);
1491
1492}
1493
1494
1495static void TestConstruction1()
1496{
1497    UResourceBundle *test1 = 0, *test2 = 0,*empty = 0;
1498    const UChar *result1, *result2;
1499    UErrorCode status= U_ZERO_ERROR;
1500    UErrorCode   err = U_ZERO_ERROR;
1501    const char*      locale="te_IN";
1502    const char* testdatapath;
1503
1504    int32_t len1=0;
1505    int32_t len2=0;
1506    UVersionInfo versionInfo;
1507    char versionString[256];
1508    char verboseOutput[256];
1509
1510    U_STRING_DECL(rootVal, "ROOT", 4);
1511    U_STRING_DECL(te_inVal, "TE_IN", 5);
1512
1513    U_STRING_INIT(rootVal, "ROOT", 4);
1514    U_STRING_INIT(te_inVal, "TE_IN", 5);
1515
1516    testdatapath=loadTestData(&status);
1517    if(U_FAILURE(status))
1518    {
1519        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
1520        return;
1521    }
1522
1523    log_verbose("Testing ures_open()......\n");
1524
1525    empty = ures_open(testdatapath, "testempty", &status);
1526    if(empty == NULL || U_FAILURE(status)) {
1527        log_err("opening empty failed!\n");
1528    }
1529    ures_close(empty);
1530
1531    test1=ures_open(testdatapath, NULL, &err);
1532
1533    if(U_FAILURE(err))
1534    {
1535        log_err("construction of NULL did not succeed :  %s \n", myErrorName(status));
1536        return;
1537    }
1538    test2=ures_open(testdatapath, locale, &err);
1539    if(U_FAILURE(err))
1540    {
1541        log_err("construction of %s did not succeed :  %s \n", locale, myErrorName(status));
1542        return;
1543    }
1544    result1= tres_getString(test1, -1, "string_in_Root_te_te_IN", &len1, &err);
1545    result2= tres_getString(test2, -1, "string_in_Root_te_te_IN", &len2, &err);
1546    if (U_FAILURE(err) || len1==0 || len2==0) {
1547        log_err("Something threw an error in TestConstruction(): %s\n", myErrorName(status));
1548        return;
1549    }
1550    log_verbose("for string_in_Root_te_te_IN, default.txt had  %s\n", u_austrcpy(verboseOutput, result1));
1551    log_verbose("for string_in_Root_te_te_IN, te_IN.txt had %s\n", u_austrcpy(verboseOutput, result2));
1552    if(u_strcmp(result1, rootVal) !=0  || u_strcmp(result2, te_inVal) !=0 ){
1553        log_err("construction test failed. Run Verbose for more information");
1554    }
1555
1556
1557    /* Test getVersionNumber*/
1558    log_verbose("Testing version number\n");
1559    log_verbose("for getVersionNumber :  %s\n", ures_getVersionNumber(test1));
1560
1561    log_verbose("Testing version \n");
1562    ures_getVersion(test1, versionInfo);
1563    u_versionToString(versionInfo, versionString);
1564
1565    log_verbose("for getVersion :  %s\n", versionString);
1566
1567    if(strcmp(versionString, ures_getVersionNumber(test1)) != 0) {
1568        log_err("Versions differ: %s vs %s\n", versionString, ures_getVersionNumber(test1));
1569    }
1570
1571    ures_close(test1);
1572    ures_close(test2);
1573
1574}
1575
1576/*****************************************************************************/
1577/*****************************************************************************/
1578
1579static UBool testTag(const char* frag,
1580           UBool in_Root,
1581           UBool in_te,
1582           UBool in_te_IN)
1583{
1584    int32_t failNum = fail;
1585
1586    /* Make array from input params */
1587
1588    UBool is_in[3];
1589    const char *NAME[] = { "ROOT", "TE", "TE_IN" };
1590
1591    /* Now try to load the desired items */
1592    UResourceBundle* theBundle = NULL;
1593    char tag[99];
1594    char action[256];
1595    UErrorCode expected_status,status = U_ZERO_ERROR,expected_resource_status = U_ZERO_ERROR;
1596    UChar* base = NULL;
1597    UChar* expected_string = NULL;
1598    const UChar* string = NULL;
1599    char buf[5];
1600    char item_tag[10];
1601    int32_t i,j,row,col, len;
1602    int32_t actual_bundle;
1603    int32_t count = 0;
1604    int32_t row_count=0;
1605    int32_t column_count=0;
1606    int32_t idx = 0;
1607    int32_t tag_count= 0;
1608    const char* testdatapath;
1609    char verboseOutput[256];
1610    UResourceBundle* array=NULL;
1611    UResourceBundle* array2d=NULL;
1612    UResourceBundle* tags=NULL;
1613    UResourceBundle* arrayItem1=NULL;
1614
1615    testdatapath = loadTestData(&status);
1616    if(U_FAILURE(status))
1617    {
1618        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
1619        return FALSE;
1620    }
1621
1622    is_in[0] = in_Root;
1623    is_in[1] = in_te;
1624    is_in[2] = in_te_IN;
1625
1626    strcpy(item_tag, "tag");
1627
1628    for (i=0; i<bundles_count; ++i)
1629    {
1630        strcpy(action,"construction for ");
1631        strcat(action, param[i].name);
1632
1633
1634        status = U_ZERO_ERROR;
1635
1636        theBundle = ures_open(testdatapath, param[i].name, &status);
1637        CONFIRM_ErrorCode(status,param[i].expected_constructor_status);
1638
1639        if(i == 5)
1640            actual_bundle = 0; /* ne -> default */
1641        else if(i == 3)
1642            actual_bundle = 1; /* te_NE -> te */
1643        else if(i == 4)
1644            actual_bundle = 2; /* te_IN_NE -> te_IN */
1645        else
1646            actual_bundle = i;
1647
1648        expected_resource_status = U_MISSING_RESOURCE_ERROR;
1649        for (j=e_te_IN; j>=e_Root; --j)
1650        {
1651            if (is_in[j] && param[i].inherits[j])
1652            {
1653
1654                if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
1655                    expected_resource_status = U_ZERO_ERROR;
1656                else if(j == 0)
1657                    expected_resource_status = U_USING_DEFAULT_WARNING;
1658                else
1659                    expected_resource_status = U_USING_FALLBACK_WARNING;
1660
1661                log_verbose("%s[%d]::%s: in<%d:%s> inherits<%d:%s>.  actual_bundle=%s\n",
1662                            param[i].name,
1663                            i,
1664                            frag,
1665                            j,
1666                            is_in[j]?"Yes":"No",
1667                            j,
1668                            param[i].inherits[j]?"Yes":"No",
1669                            param[actual_bundle].name);
1670
1671                break;
1672            }
1673        }
1674
1675        for (j=param[i].where; j>=0; --j)
1676        {
1677            if (is_in[j])
1678            {
1679                if(base != NULL) {
1680                    free(base);
1681                    base = NULL;
1682                }
1683                base=(UChar*)malloc(sizeof(UChar)*(strlen(NAME[j]) + 1));
1684                u_uastrcpy(base,NAME[j]);
1685
1686                break;
1687            }
1688            else {
1689                if(base != NULL) {
1690                    free(base);
1691                    base = NULL;
1692                }
1693                base = (UChar*) malloc(sizeof(UChar) * 1);
1694                *base = 0x0000;
1695            }
1696        }
1697
1698        /*----string---------------------------------------------------------------- */
1699
1700        strcpy(tag,"string_");
1701        strcat(tag,frag);
1702
1703        strcpy(action,param[i].name);
1704        strcat(action, ".ures_getStringByKey(" );
1705        strcat(action,tag);
1706        strcat(action, ")");
1707
1708
1709        status = U_ZERO_ERROR;
1710        len=0;
1711
1712        string=tres_getString(theBundle, -1, tag, &len, &status);
1713        if(U_SUCCESS(status)) {
1714            expected_string=(UChar*)malloc(sizeof(UChar)*(u_strlen(base) + 4));
1715            u_strcpy(expected_string,base);
1716            CONFIRM_INT_EQ(len, u_strlen(expected_string));
1717        }else{
1718            expected_string = (UChar*)malloc(sizeof(UChar)*(u_strlen(kERROR) + 1));
1719            u_strcpy(expected_string,kERROR);
1720            string=kERROR;
1721        }
1722        log_verbose("%s got %d, expected %d\n", action, status, expected_resource_status);
1723
1724        CONFIRM_ErrorCode(status, expected_resource_status);
1725        CONFIRM_EQ(string, expected_string);
1726
1727
1728
1729        /*--------------array------------------------------------------------- */
1730
1731        strcpy(tag,"array_");
1732        strcat(tag,frag);
1733
1734        strcpy(action,param[i].name);
1735        strcat(action, ".ures_getByKey(" );
1736        strcat(action,tag);
1737        strcat(action, ")");
1738
1739        len=0;
1740
1741        count = kERROR_COUNT;
1742        status = U_ZERO_ERROR;
1743        array=ures_getByKey(theBundle, tag, array, &status);
1744        CONFIRM_ErrorCode(status,expected_resource_status);
1745        if (U_SUCCESS(status)) {
1746            /*confirm the resource type is an array*/
1747            CONFIRM_INT_EQ(ures_getType(array), URES_ARRAY);
1748            /*confirm the size*/
1749            count=ures_getSize(array);
1750            CONFIRM_INT_GE(count,1);
1751            for (j=0; j<count; ++j) {
1752                UChar element[3];
1753                u_strcpy(expected_string, base);
1754                u_uastrcpy(element, itoa1(j,buf));
1755                u_strcat(expected_string, element);
1756                arrayItem1=ures_getNextResource(array, arrayItem1, &status);
1757                if(U_SUCCESS(status)){
1758                    CONFIRM_EQ(tres_getString(arrayItem1, -1, NULL, &len, &status),expected_string);
1759                }
1760            }
1761
1762        }
1763        else {
1764            CONFIRM_INT_EQ(count,kERROR_COUNT);
1765            CONFIRM_ErrorCode(status, U_MISSING_RESOURCE_ERROR);
1766            /*CONFIRM_INT_EQ((int32_t)(unsigned long)array,(int32_t)0);*/
1767            count = 0;
1768        }
1769
1770        /*--------------arrayItem------------------------------------------------- */
1771
1772        strcpy(tag,"array_");
1773        strcat(tag,frag);
1774
1775        strcpy(action,param[i].name);
1776        strcat(action, ".ures_getStringByIndex(");
1777        strcat(action, tag);
1778        strcat(action, ")");
1779
1780
1781        for (j=0; j<10; ++j){
1782            idx = count ? (randi(count * 3) - count) : (randi(200) - 100);
1783            status = U_ZERO_ERROR;
1784            string=kERROR;
1785            array=ures_getByKey(theBundle, tag, array, &status);
1786            if(!U_FAILURE(status)){
1787                UChar *t=NULL;
1788                t=(UChar*)ures_getStringByIndex(array, idx, &len, &status);
1789                if(!U_FAILURE(status)){
1790                    UChar element[3];
1791                    string=t;
1792                    u_strcpy(expected_string, base);
1793                    u_uastrcpy(element, itoa1(idx,buf));
1794                    u_strcat(expected_string, element);
1795                } else {
1796                    u_strcpy(expected_string, kERROR);
1797                }
1798
1799            }
1800            expected_status = (idx >= 0 && idx < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR;
1801            CONFIRM_ErrorCode(status,expected_status);
1802            CONFIRM_EQ(string,expected_string);
1803
1804        }
1805
1806
1807        /*--------------2dArray------------------------------------------------- */
1808
1809        strcpy(tag,"array_2d_");
1810        strcat(tag,frag);
1811
1812        strcpy(action,param[i].name);
1813        strcat(action, ".ures_getByKey(" );
1814        strcat(action,tag);
1815        strcat(action, ")");
1816
1817
1818
1819        row_count = kERROR_COUNT, column_count = kERROR_COUNT;
1820        status = U_ZERO_ERROR;
1821        array2d=ures_getByKey(theBundle, tag, array2d, &status);
1822
1823        CONFIRM_ErrorCode(status,expected_resource_status);
1824        if (U_SUCCESS(status))
1825        {
1826            /*confirm the resource type is an 2darray*/
1827            CONFIRM_INT_EQ(ures_getType(array2d), URES_ARRAY);
1828            row_count=ures_getSize(array2d);
1829            CONFIRM_INT_GE(row_count,1);
1830
1831            for(row=0; row<row_count; ++row){
1832                UResourceBundle *tableRow=NULL;
1833                tableRow=ures_getByIndex(array2d, row, tableRow, &status);
1834                CONFIRM_ErrorCode(status, expected_resource_status);
1835                if(U_SUCCESS(status)){
1836                    /*confirm the resourcetype of each table row is an array*/
1837                    CONFIRM_INT_EQ(ures_getType(tableRow), URES_ARRAY);
1838                    column_count=ures_getSize(tableRow);
1839                    CONFIRM_INT_GE(column_count,1);
1840
1841                    for (col=0; j<column_count; ++j) {
1842                        UChar element[3];
1843                        u_strcpy(expected_string, base);
1844                        u_uastrcpy(element, itoa1(row, buf));
1845                        u_strcat(expected_string, element);
1846                        u_uastrcpy(element, itoa1(col, buf));
1847                        u_strcat(expected_string, element);
1848                        arrayItem1=ures_getNextResource(tableRow, arrayItem1, &status);
1849                        if(U_SUCCESS(status)){
1850                            const UChar *stringValue=tres_getString(arrayItem1, -1, NULL, &len, &status);
1851                            CONFIRM_EQ(stringValue, expected_string);
1852                        }
1853                    }
1854                }
1855                ures_close(tableRow);
1856            }
1857        }else{
1858            CONFIRM_INT_EQ(row_count,kERROR_COUNT);
1859            CONFIRM_INT_EQ(column_count,kERROR_COUNT);
1860            row_count=column_count=0;
1861        }
1862
1863
1864        /*------2dArrayItem-------------------------------------------------------------- */
1865        /* 2dArrayItem*/
1866        for (j=0; j<10; ++j)
1867        {
1868            row = row_count ? (randi(row_count * 3) - row_count) : (randi(200) - 100);
1869            col = column_count ? (randi(column_count * 3) - column_count) : (randi(200) - 100);
1870            status = U_ZERO_ERROR;
1871            string = kERROR;
1872            len=0;
1873            array2d=ures_getByKey(theBundle, tag, array2d, &status);
1874            if(U_SUCCESS(status)){
1875                UResourceBundle *tableRow=NULL;
1876                tableRow=ures_getByIndex(array2d, row, tableRow, &status);
1877                if(U_SUCCESS(status)) {
1878                    UChar *t=NULL;
1879                    t=(UChar*)ures_getStringByIndex(tableRow, col, &len, &status);
1880                    if(U_SUCCESS(status)){
1881                        string=t;
1882                    }
1883                }
1884                ures_close(tableRow);
1885            }
1886            expected_status = (row >= 0 && row < row_count && col >= 0 && col < column_count) ?
1887                                   expected_resource_status: U_MISSING_RESOURCE_ERROR;
1888            CONFIRM_ErrorCode(status,expected_status);
1889
1890            if (U_SUCCESS(status)){
1891                UChar element[3];
1892                u_strcpy(expected_string, base);
1893                u_uastrcpy(element, itoa1(row, buf));
1894                u_strcat(expected_string, element);
1895                u_uastrcpy(element, itoa1(col, buf));
1896                u_strcat(expected_string, element);
1897            } else {
1898                u_strcpy(expected_string,kERROR);
1899            }
1900            CONFIRM_EQ(string,expected_string);
1901
1902        }
1903
1904
1905        /*--------------taggedArray----------------------------------------------- */
1906        strcpy(tag,"tagged_array_");
1907        strcat(tag,frag);
1908
1909        strcpy(action,param[i].name);
1910        strcat(action,".ures_getByKey(");
1911        strcat(action, tag);
1912        strcat(action,")");
1913
1914
1915        status = U_ZERO_ERROR;
1916        tag_count=0;
1917        tags=ures_getByKey(theBundle, tag, tags, &status);
1918        CONFIRM_ErrorCode(status, expected_resource_status);
1919        if (U_SUCCESS(status)) {
1920            UResType bundleType=ures_getType(tags);
1921            CONFIRM_INT_EQ(bundleType, URES_TABLE);
1922
1923            tag_count=ures_getSize(tags);
1924            CONFIRM_INT_GE((int32_t)tag_count, (int32_t)0);
1925
1926            for(idx=0; idx <tag_count; idx++){
1927                UResourceBundle *tagelement=NULL;
1928                const char *key=NULL;
1929                UChar* value=NULL;
1930                tagelement=ures_getByIndex(tags, idx, tagelement, &status);
1931                key=ures_getKey(tagelement);
1932                value=(UChar*)ures_getNextString(tagelement, &len, &key, &status);
1933                log_verbose("tag = %s, value = %s\n", key, u_austrcpy(verboseOutput, value));
1934                if(strncmp(key, "tag", 3) == 0 && u_strncmp(value, base, u_strlen(base)) == 0){
1935                    record_pass();
1936                }else{
1937                    record_fail();
1938                }
1939                ures_close(tagelement);
1940            }
1941        }else{
1942            tag_count=0;
1943        }
1944
1945        /*---------taggedArrayItem----------------------------------------------*/
1946        count = 0;
1947        for (idx=-20; idx<20; ++idx)
1948        {
1949
1950            status = U_ZERO_ERROR;
1951            string = kERROR;
1952            strcpy(item_tag, "tag");
1953            strcat(item_tag, itoa1(idx,buf));
1954            tags=ures_getByKey(theBundle, tag, tags, &status);
1955            if(U_SUCCESS(status)){
1956                UResourceBundle *tagelement=NULL;
1957                UChar *t=NULL;
1958                tagelement=ures_getByKey(tags, item_tag, tagelement, &status);
1959                if(!U_FAILURE(status)){
1960                    UResType elementType=ures_getType(tagelement);
1961                    CONFIRM_INT_EQ(elementType, URES_STRING);
1962                    if(strcmp(ures_getKey(tagelement), item_tag) == 0){
1963                        record_pass();
1964                    }else{
1965                        record_fail();
1966                    }
1967                    t=(UChar*)tres_getString(tagelement, -1, NULL, &len, &status);
1968                    if(!U_FAILURE(status)){
1969                        string=t;
1970                    }
1971                }
1972                if (idx < 0) {
1973                    CONFIRM_ErrorCode(status,U_MISSING_RESOURCE_ERROR);
1974                }
1975                else{
1976                    if (status != U_MISSING_RESOURCE_ERROR) {
1977                        UChar element[3];
1978                        u_strcpy(expected_string, base);
1979                        u_uastrcpy(element, itoa1(idx,buf));
1980                        u_strcat(expected_string, element);
1981                        CONFIRM_EQ(string,expected_string);
1982                        count++;
1983                    }
1984                }
1985                ures_close(tagelement);
1986            }
1987        }
1988        CONFIRM_INT_EQ(count, tag_count);
1989
1990        free(expected_string);
1991        ures_close(theBundle);
1992    }
1993    ures_close(array);
1994    ures_close(array2d);
1995    ures_close(tags);
1996    ures_close(arrayItem1);
1997    free(base);
1998    return (UBool)(failNum == fail);
1999}
2000
2001static void record_pass()
2002{
2003    ++pass;
2004}
2005
2006static void record_fail()
2007{
2008    ++fail;
2009}
2010
2011static void TestPreventFallback() {
2012    UResourceBundle* theBundle = NULL;
2013    const char* testdatapath;
2014    UErrorCode status = U_ZERO_ERROR;
2015    int32_t unused_len = 0;
2016
2017    testdatapath=loadTestData(&status);
2018    if(U_FAILURE(status))
2019    {
2020        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
2021        return;
2022    }
2023
2024    // In te_IN locale, fallback of string_in_te_no_te_IN_fallback is blocked
2025    // with the three empty-set (U+2205) chars.
2026    theBundle = ures_open(testdatapath, "te_IN_NE", &status);
2027    if(U_FAILURE(status))
2028    {
2029        log_data_err("Could not open resource bundle te_IN_NE %s \n",myErrorName(status));
2030        return;
2031    }
2032
2033    // Fallback is blocked
2034    ures_getStringByKeyWithFallback(theBundle, "string_in_te_no_te_IN_fallback", &unused_len, &status);
2035    if (status != U_MISSING_RESOURCE_ERROR)
2036    {
2037        log_err("Expected missing resource error for string_in_te_no_te_IN_fallback.");
2038    }
2039    status = U_ZERO_ERROR;
2040
2041    // This fallback should succeed
2042    ures_getStringByKeyWithFallback(theBundle, "string_only_in_te", &unused_len, &status);
2043    if(U_FAILURE(status))
2044    {
2045        log_err("Expected to find string_only_in_te %s \n",myErrorName(status));
2046    }
2047    status = U_ZERO_ERROR;
2048    ures_close(theBundle);
2049
2050    // From te locale, we should be able to fetch string_in_te_no_te_IN_fallback.
2051    theBundle = ures_open(testdatapath, "te", &status);
2052    if(U_FAILURE(status))
2053    {
2054        log_data_err("Could not open resource bundle te_IN_NE %s \n",myErrorName(status));
2055        return;
2056    }
2057    ures_getStringByKeyWithFallback(theBundle, "string_in_te_no_te_IN_fallback", &unused_len, &status);
2058    if(U_FAILURE(status))
2059    {
2060        log_err("Expected to find string_in_te_no_te_IN_fallback %s \n",myErrorName(status));
2061    }
2062    status = U_ZERO_ERROR;
2063    ures_close(theBundle);
2064}
2065
2066/**
2067 * Test to make sure that the U_USING_FALLBACK_ERROR and U_USING_DEFAULT_ERROR
2068 * are set correctly
2069 */
2070
2071static void TestFallback()
2072{
2073    UErrorCode status = U_ZERO_ERROR;
2074    UResourceBundle *fr_FR = NULL;
2075    UResourceBundle *subResource = NULL;
2076    const UChar *junk; /* ignored */
2077    int32_t resultLen;
2078
2079    log_verbose("Opening fr_FR..");
2080    fr_FR = ures_open(NULL, "fr_FR", &status);
2081    if(U_FAILURE(status))
2082    {
2083        log_err_status(status, "Couldn't open fr_FR - %s\n", u_errorName(status));
2084        return;
2085    }
2086
2087    status = U_ZERO_ERROR;
2088
2089
2090    /* clear it out..  just do some calls to get the gears turning */
2091    junk = tres_getString(fr_FR, -1, "LocaleID", &resultLen, &status);
2092    status = U_ZERO_ERROR;
2093    junk = tres_getString(fr_FR, -1, "LocaleString", &resultLen, &status);
2094    status = U_ZERO_ERROR;
2095    junk = tres_getString(fr_FR, -1, "LocaleID", &resultLen, &status);
2096    status = U_ZERO_ERROR;
2097    (void)junk;    /* Suppress set but not used warning. */
2098
2099    /* OK first one. This should be a Default value. */
2100    subResource = ures_getByKey(fr_FR, "layout", NULL, &status);
2101    if(status != U_USING_DEFAULT_WARNING)
2102    {
2103        log_data_err("Expected U_USING_DEFAULT_ERROR when trying to get layout from fr_FR, got %s\n",
2104            u_errorName(status));
2105    }
2106
2107    status = U_ZERO_ERROR;
2108    ures_close(subResource);
2109
2110    /* and this is a Fallback, to fr */
2111    junk = tres_getString(fr_FR, -1, "ExemplarCharacters", &resultLen, &status);
2112    if(status != U_USING_FALLBACK_WARNING)
2113    {
2114        log_data_err("Expected U_USING_FALLBACK_ERROR when trying to get ExemplarCharacters from fr_FR, got %d\n",
2115            status);
2116    }
2117
2118    status = U_ZERO_ERROR;
2119
2120    ures_close(fr_FR);
2121    /* Temporary hack err actually should be U_USING_FALLBACK_ERROR */
2122    /* Test Jitterbug 552 fallback mechanism of aliased data */
2123    {
2124        UErrorCode err =U_ZERO_ERROR;
2125        UResourceBundle* myResB = ures_open(NULL,"no_NO_NY",&err);
2126        UResourceBundle* resLocID = ures_getByKey(myResB, "Version", NULL, &err);
2127        UResourceBundle* tResB;
2128        UResourceBundle* zoneResource;
2129        const UChar* version = NULL;
2130        static const UChar versionStr[] = { 0x0032, 0x002E, 0x0031, 0x002E, 0x0032, 0x0037, 0x002E, 0x0034, 0x0030, 0x0000}; // 2.1.27.40 in nn_NO
2131
2132        if(err != U_ZERO_ERROR){
2133            log_data_err("Expected U_ZERO_ERROR when trying to test no_NO_NY aliased to nn_NO for Version err=%s\n",u_errorName(err));
2134            return;
2135        }
2136        version = tres_getString(resLocID, -1, NULL, &resultLen, &err);
2137        if(u_strcmp(version, versionStr) != 0){
2138            char x[100];
2139            char g[100];
2140            u_austrcpy(x, versionStr);
2141            u_austrcpy(g, version);
2142            log_data_err("ures_getString(resLocID, &resultLen, &err) returned an unexpected version value. Expected '%s', but got '%s'\n",
2143                    x, g);
2144        }
2145        zoneResource = ures_open(U_ICUDATA_ZONE, "no_NO_NY", &err);
2146        tResB = ures_getByKey(zoneResource, "zoneStrings", NULL, &err);
2147        if(err != U_USING_FALLBACK_WARNING){
2148            log_err("Expected U_USING_FALLBACK_ERROR when trying to test no_NO_NY aliased with nn_NO_NY for zoneStrings err=%s\n",u_errorName(err));
2149        }
2150        ures_close(tResB);
2151        ures_close(zoneResource);
2152        ures_close(resLocID);
2153        ures_close(myResB);
2154    }
2155
2156}
2157
2158/* static void printUChars(UChar* uchars){
2159/    int16_t i=0;
2160/    for(i=0; i<u_strlen(uchars); i++){
2161/        log_err("%04X ", *(uchars+i));
2162/    }
2163/ } */
2164
2165static void TestResourceLevelAliasing(void) {
2166    UErrorCode status = U_ZERO_ERROR;
2167    UResourceBundle *aliasB = NULL, *tb = NULL;
2168    UResourceBundle *en = NULL, *uk = NULL, *testtypes = NULL;
2169    const char* testdatapath = NULL;
2170    const UChar *string = NULL, *sequence = NULL;
2171    /*const uint8_t *binary = NULL, *binSequence = NULL;*/
2172    int32_t strLen = 0, seqLen = 0;/*, binLen = 0, binSeqLen = 0;*/
2173    char buffer[100];
2174    char *s;
2175
2176    testdatapath=loadTestData(&status);
2177    if(U_FAILURE(status))
2178    {
2179        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
2180        return;
2181    }
2182
2183    aliasB = ures_open(testdatapath, "testaliases", &status);
2184
2185    if(U_FAILURE(status))
2186    {
2187        log_data_err("Could not load testaliases.res %s \n",myErrorName(status));
2188        return;
2189    }
2190    /* this should fail - circular alias */
2191    tb = ures_getByKey(aliasB, "aaa", tb, &status);
2192    if(status != U_TOO_MANY_ALIASES_ERROR) {
2193        log_err("Failed to detect circular alias\n");
2194    }
2195    else {
2196        status = U_ZERO_ERROR;
2197    }
2198    tb = ures_getByKey(aliasB, "aab", tb, &status);
2199    if(status != U_TOO_MANY_ALIASES_ERROR) {
2200        log_err("Failed to detect circular alias\n");
2201    } else {
2202        status = U_ZERO_ERROR;
2203    }
2204    if(U_FAILURE(status) ) {
2205        log_data_err("err loading tb resource\n");
2206    }  else {
2207      /* testing aliasing to a non existing resource */
2208      tb = ures_getByKey(aliasB, "nonexisting", tb, &status);
2209      if(status != U_MISSING_RESOURCE_ERROR) {
2210        log_err("Managed to find an alias to non-existing resource\n");
2211      } else {
2212        status = U_ZERO_ERROR;
2213      }
2214      /* testing referencing/composed alias */
2215      uk = ures_findResource("ja/calendar/gregorian/DateTimePatterns/2", uk, &status);
2216      if((uk == NULL) || U_FAILURE(status)) {
2217        log_err_status(status, "Couldn't findResource('ja/calendar/gregorian/DateTimePatterns/2') err %s\n", u_errorName(status));
2218        goto cleanup;
2219      }
2220
2221      sequence = tres_getString(uk, -1, NULL, &seqLen, &status);
2222
2223      tb = ures_getByKey(aliasB, "referencingalias", tb, &status);
2224      string = tres_getString(tb, -1, NULL, &strLen, &status);
2225
2226      if(seqLen != strLen || u_strncmp(sequence, string, seqLen) != 0) {
2227        log_err("Referencing alias didn't get the right string (1)\n");
2228      }
2229
2230      string = tres_getString(aliasB, -1, "referencingalias", &strLen, &status);
2231      if(seqLen != strLen || u_strncmp(sequence, string, seqLen) != 0) {
2232        log_err("Referencing alias didn't get the right string (2)\n");
2233      }
2234
2235      checkStatus(__LINE__, U_ZERO_ERROR, status);
2236      tb = ures_getByKey(aliasB, "DateTimePatterns", tb, &status);
2237      checkStatus(__LINE__, U_ZERO_ERROR, status);
2238      tb = ures_getByIndex(tb, 2, tb, &status);
2239      checkStatus(__LINE__, U_ZERO_ERROR, status);
2240      string = tres_getString(tb, -1, NULL, &strLen, &status);
2241      checkStatus(__LINE__, U_ZERO_ERROR, status);
2242
2243      if(U_FAILURE(status)) {
2244        log_err("%s trying to get string via separate getters\n", u_errorName(status));
2245      } else if(seqLen != strLen || u_strncmp(sequence, string, seqLen) != 0) {
2246        log_err("Referencing alias didn't get the right string (3)\n");
2247      }
2248
2249      /* simple alias */
2250      testtypes = ures_open(testdatapath, "testtypes", &status);
2251      strcpy(buffer, "menu/file/open");
2252      s = buffer;
2253      uk = ures_findSubResource(testtypes, s, uk, &status);
2254      sequence = tres_getString(uk, -1, NULL, &seqLen, &status);
2255
2256      tb = ures_getByKey(aliasB, "simplealias", tb, &status);
2257      string = tres_getString(tb, -1, NULL, &strLen, &status);
2258
2259      if(U_FAILURE(status) || seqLen != strLen || u_strncmp(sequence, string, seqLen) != 0) {
2260        log_err("Referencing alias didn't get the right string (4)\n");
2261      }
2262
2263      /* test indexed aliasing */
2264
2265      tb = ures_getByKey(aliasB, "zoneTests", tb, &status);
2266      tb = ures_getByKey(tb, "zoneAlias2", tb, &status);
2267      string = tres_getString(tb, -1, NULL, &strLen, &status);
2268
2269      en = ures_findResource("/ICUDATA-zone/en/zoneStrings/3/0", en, &status);
2270      sequence = tres_getString(en, -1, NULL, &seqLen, &status);
2271
2272      if(U_FAILURE(status) || seqLen != strLen || u_strncmp(sequence, string, seqLen) != 0) {
2273        log_err("Referencing alias didn't get the right string (5)\n");
2274      }
2275    }
2276    /* test getting aliased string by index */
2277    {
2278        const char* keys[] = {
2279                "KeyAlias0PST",
2280                "KeyAlias1PacificStandardTime",
2281                "KeyAlias2PDT",
2282                "KeyAlias3LosAngeles"
2283        };
2284
2285        const char* strings[] = {
2286                "America/Los_Angeles",
2287                "Pacific Standard Time",
2288                "PDT",
2289                "Los Angeles",
2290        };
2291        UChar uBuffer[256];
2292        const UChar* result;
2293        int32_t uBufferLen = 0, resultLen = 0;
2294        int32_t i = 0;
2295        const char *key = NULL;
2296        tb = ures_getByKey(aliasB, "testGetStringByKeyAliasing", tb, &status);
2297        if(U_FAILURE(status)) {
2298          log_err("FAIL: Couldn't get testGetStringByKeyAliasing resource: %s\n", u_errorName(status));
2299        } else {
2300            for(i = 0; i < UPRV_LENGTHOF(strings); i++) {
2301                result = tres_getString(tb, -1, keys[i], &resultLen, &status);
2302                if(U_FAILURE(status)){
2303                    log_err("(1) Fetching the resource with key %s failed. Error: %s\n", keys[i], u_errorName(status));
2304                    continue;
2305                }
2306                uBufferLen = u_unescape(strings[i], uBuffer, 256);
2307                if(resultLen != uBufferLen || u_strncmp(result, uBuffer, resultLen) != 0) {
2308                  log_err("(1) Didn't get correct string while accessing alias table by key (%s)\n", keys[i]);
2309                }
2310            }
2311            for(i = 0; i < UPRV_LENGTHOF(strings); i++) {
2312                result = tres_getString(tb, i, NULL, &resultLen, &status);
2313                if(U_FAILURE(status)){
2314                    log_err("(2) Fetching the resource with key %s failed. Error: %s\n", keys[i], u_errorName(status));
2315                    continue;
2316                }
2317                uBufferLen = u_unescape(strings[i], uBuffer, 256);
2318                if(result==NULL || resultLen != uBufferLen || u_strncmp(result, uBuffer, resultLen) != 0) {
2319                  log_err("(2) Didn't get correct string while accesing alias table by index (%s)\n", strings[i]);
2320                }
2321            }
2322            for(i = 0; i < UPRV_LENGTHOF(strings); i++) {
2323                result = ures_getNextString(tb, &resultLen, &key, &status);
2324                if(U_FAILURE(status)){
2325                    log_err("(3) Fetching the resource with key %s failed. Error: %s\n", keys[i], u_errorName(status));
2326                    continue;
2327                }
2328                uBufferLen = u_unescape(strings[i], uBuffer, 256);
2329                if(result==NULL || resultLen != uBufferLen || u_strncmp(result, uBuffer, resultLen) != 0) {
2330                  log_err("(3) Didn't get correct string while iterating over alias table (%s)\n", strings[i]);
2331                }
2332            }
2333        }
2334        tb = ures_getByKey(aliasB, "testGetStringByIndexAliasing", tb, &status);
2335        if(U_FAILURE(status)) {
2336          log_err("FAIL: Couldn't get testGetStringByIndexAliasing resource: %s\n", u_errorName(status));
2337        } else {
2338            for(i = 0; i < UPRV_LENGTHOF(strings); i++) {
2339                result = tres_getString(tb, i, NULL, &resultLen, &status);
2340                if(U_FAILURE(status)){
2341                    log_err("Fetching the resource with key %s failed. Error: %s\n", keys[i], u_errorName(status));
2342                    continue;
2343                }
2344                uBufferLen = u_unescape(strings[i], uBuffer, 256);
2345                if(result==NULL || resultLen != uBufferLen || u_strncmp(result, uBuffer, resultLen) != 0) {
2346                  log_err("Didn't get correct string while accesing alias by index in an array (%s)\n", strings[i]);
2347                }
2348            }
2349            for(i = 0; i < UPRV_LENGTHOF(strings); i++) {
2350                result = ures_getNextString(tb, &resultLen, &key, &status);
2351                if(U_FAILURE(status)){
2352                    log_err("Fetching the resource with key %s failed. Error: %s\n", keys[i], u_errorName(status));
2353                    continue;
2354                }
2355                uBufferLen = u_unescape(strings[i], uBuffer, 256);
2356                if(result==NULL || resultLen != uBufferLen || u_strncmp(result, uBuffer, resultLen) != 0) {
2357                  log_err("Didn't get correct string while iterating over aliases in an array (%s)\n", strings[i]);
2358                }
2359            }
2360        }
2361    }
2362    tb = ures_getByKey(aliasB, "testAliasToTree", tb, &status);
2363    if(U_FAILURE(status)){
2364        log_err("Fetching the resource with key \"testAliasToTree\" failed. Error: %s\n", u_errorName(status));
2365        goto cleanup;
2366    }
2367    if (strcmp(ures_getKey(tb), "collations") != 0) {
2368        log_err("ures_getKey(aliasB) unexpectedly returned %s instead of \"collations\"\n", ures_getKey(tb));
2369    }
2370cleanup:
2371    ures_close(aliasB);
2372    ures_close(tb);
2373    ures_close(en);
2374    ures_close(uk);
2375    ures_close(testtypes);
2376}
2377
2378static void TestDirectAccess(void) {
2379    UErrorCode status = U_ZERO_ERROR;
2380    UResourceBundle *t = NULL, *t2 = NULL;
2381    const char* key = NULL;
2382
2383    char buffer[100];
2384    char *s;
2385    /*const char* testdatapath=loadTestData(&status);
2386    if(U_FAILURE(status)){
2387        log_err("Could not load testdata.dat %s \n",myErrorName(status));
2388        return;
2389    }*/
2390
2391    t = ures_findResource("/testdata/te/zoneStrings/3/2", t, &status);
2392    if(U_FAILURE(status)) {
2393        log_data_err("Couldn't access indexed resource, error %s\n", u_errorName(status));
2394        status = U_ZERO_ERROR;
2395    } else {
2396        key = ures_getKey(t);
2397        if(key != NULL) {
2398            log_err("Got a strange key, expected NULL, got %s\n", key);
2399        }
2400    }
2401    t = ures_findResource("en/calendar/gregorian/DateTimePatterns/3", t, &status);
2402    if(U_FAILURE(status)) {
2403        log_data_err("Couldn't access indexed resource, error %s\n", u_errorName(status));
2404        status = U_ZERO_ERROR;
2405    } else {
2406        key = ures_getKey(t);
2407        if(key != NULL) {
2408            log_err("Got a strange key, expected NULL, got %s\n", key);
2409        }
2410    }
2411
2412    t = ures_findResource("ja/ExemplarCharacters", t, &status);
2413    if(U_FAILURE(status)) {
2414        log_data_err("Couldn't access keyed resource, error %s\n", u_errorName(status));
2415        status = U_ZERO_ERROR;
2416    } else {
2417        key = ures_getKey(t);
2418        if(strcmp(key, "ExemplarCharacters")!=0) {
2419            log_err("Got a strange key, expected 'ExemplarCharacters', got %s\n", key);
2420        }
2421    }
2422
2423    t2 = ures_open(U_ICUDATA_LANG, "sr", &status);
2424    if(U_FAILURE(status)) {
2425        log_err_status(status, "Couldn't open 'sr' resource bundle, error %s\n", u_errorName(status));
2426        log_data_err("No 'sr', no test - you have bigger problems than testing direct access. "
2427                     "You probably have no data! Aborting this test\n");
2428    }
2429
2430    if(U_SUCCESS(status)) {
2431        strcpy(buffer, "Languages/hr");
2432        s = buffer;
2433        t = ures_findSubResource(t2, s, t, &status);
2434        if(U_FAILURE(status)) {
2435            log_err("Couldn't access keyed resource, error %s\n", u_errorName(status));
2436            status = U_ZERO_ERROR;
2437        } else {
2438            key = ures_getKey(t);
2439            if(strcmp(key, "hr")!=0) {
2440                log_err("Got a strange key, expected 'hr', got %s\n", key);
2441            }
2442        }
2443    }
2444
2445    t = ures_findResource("root/calendar/islamic-civil/DateTime", t, &status);
2446    if(U_SUCCESS(status)) {
2447        log_data_err("This resource does not exist. How did it get here?\n");
2448    }
2449    status = U_ZERO_ERROR;
2450
2451    /* this one will freeze */
2452    t = ures_findResource("root/calendar/islamic-civil/eras/abbreviated/0/mikimaus/pera", t, &status);
2453    if(U_SUCCESS(status)) {
2454        log_data_err("Second resource does not exist. How did it get here?\n");
2455    }
2456    status = U_ZERO_ERROR;
2457
2458    ures_close(t2);
2459    t2 = ures_open(NULL, "he", &status);
2460    t2 = ures_getByKeyWithFallback(t2, "calendar", t2, &status);
2461    t2 = ures_getByKeyWithFallback(t2, "islamic-civil", t2, &status);
2462    t2 = ures_getByKeyWithFallback(t2, "DateTime", t2, &status);
2463    if(U_SUCCESS(status)) {
2464        log_err("This resource does not exist. How did it get here?\n");
2465    }
2466    status = U_ZERO_ERROR;
2467
2468    ures_close(t2);
2469    t2 = ures_open(NULL, "he", &status);
2470    /* George's fix */
2471    t2 = ures_getByKeyWithFallback(t2, "calendar", t2, &status);
2472    t2 = ures_getByKeyWithFallback(t2, "islamic-civil", t2, &status);
2473    t2 = ures_getByKeyWithFallback(t2, "eras", t2, &status);
2474    if(U_FAILURE(status)) {
2475        log_err_status(status, "Didn't get Eras. I know they are there!\n");
2476    }
2477    status = U_ZERO_ERROR;
2478
2479    ures_close(t2);
2480    t2 = ures_open(NULL, "root", &status);
2481    t2 = ures_getByKeyWithFallback(t2, "calendar", t2, &status);
2482    t2 = ures_getByKeyWithFallback(t2, "islamic-civil", t2, &status);
2483    t2 = ures_getByKeyWithFallback(t2, "DateTime", t2, &status);
2484    if(U_SUCCESS(status)) {
2485        log_err("This resource does not exist. How did it get here?\n");
2486    }
2487    status = U_ZERO_ERROR;
2488
2489    ures_close(t2);
2490    ures_close(t);
2491}
2492
2493static void TestTicket9804(void) {
2494    UErrorCode status = U_ZERO_ERROR;
2495    UResourceBundle *t = NULL;
2496    t = ures_open(NULL, "he", &status);
2497    t = ures_getByKeyWithFallback(t, "calendar/islamic-civil/DateTime", t, &status);
2498    if(U_SUCCESS(status)) {
2499        log_err("This resource does not exist. How did it get here?\n");
2500    }
2501    status = U_ZERO_ERROR;
2502    ures_close(t);
2503    t = ures_open(NULL, "he", &status);
2504    t = ures_getByKeyWithFallback(t, "calendar/islamic-civil/eras", t, &status);
2505    if(U_FAILURE(status)) {
2506        log_err_status(status, "Didn't get Eras. I know they are there!\n");
2507    } else {
2508        const char *locale = ures_getLocaleByType(t, ULOC_ACTUAL_LOCALE, &status);
2509        if (uprv_strcmp("he", locale) != 0) {
2510            log_err("Eras should be in the 'he' locale, but was in: %s", locale);
2511        }
2512    }
2513    status = U_ZERO_ERROR;
2514    ures_close(t);
2515}
2516
2517static void TestJB3763(void) {
2518    /* Nasty bug prevented using parent as fill-in, since it would
2519     * stomp the path information.
2520     */
2521    UResourceBundle *t = NULL;
2522    UErrorCode status = U_ZERO_ERROR;
2523    t = ures_open(NULL, "sr_Latn", &status);
2524    t = ures_getByKeyWithFallback(t, "calendar", t, &status);
2525    t = ures_getByKeyWithFallback(t, "gregorian", t, &status);
2526    t = ures_getByKeyWithFallback(t, "AmPmMarkers", t, &status);
2527    if(U_FAILURE(status)) {
2528        log_err_status(status, "This resource should be available?\n");
2529    }
2530    status = U_ZERO_ERROR;
2531
2532    ures_close(t);
2533
2534}
2535
2536static void TestGetKeywordValues(void) {
2537    UEnumeration *kwVals;
2538    UBool foundStandard = FALSE;
2539    UErrorCode status = U_ZERO_ERROR;
2540    const char *kw;
2541#if !UCONFIG_NO_COLLATION
2542    kwVals = ures_getKeywordValues( U_ICUDATA_COLL, "collations", &status);
2543
2544    log_verbose("Testing getting collation keyword values:\n");
2545
2546    while((kw=uenum_next(kwVals, NULL, &status))) {
2547        log_verbose("  %s\n", kw);
2548        if(!strcmp(kw,"standard")) {
2549            if(foundStandard == FALSE) {
2550                foundStandard = TRUE;
2551            } else {
2552                log_err("'standard' was found twice in the keyword list.\n");
2553            }
2554        }
2555    }
2556    if(foundStandard == FALSE) {
2557        log_err_status(status, "'standard' was not found in the keyword list.\n");
2558    }
2559    uenum_close(kwVals);
2560    if(U_FAILURE(status)) {
2561        log_err_status(status, "err %s getting collation values\n", u_errorName(status));
2562    }
2563    status = U_ZERO_ERROR;
2564#endif
2565    foundStandard = FALSE;
2566    kwVals = ures_getKeywordValues( "ICUDATA", "calendar", &status);
2567
2568    log_verbose("Testing getting calendar keyword values:\n");
2569
2570    while((kw=uenum_next(kwVals, NULL, &status))) {
2571        log_verbose("  %s\n", kw);
2572        if(!strcmp(kw,"japanese")) {
2573            if(foundStandard == FALSE) {
2574                foundStandard = TRUE;
2575            } else {
2576                log_err("'japanese' was found twice in the calendar keyword list.\n");
2577            }
2578        }
2579    }
2580    if(foundStandard == FALSE) {
2581        log_err_status(status, "'japanese' was not found in the calendar keyword list.\n");
2582    }
2583    uenum_close(kwVals);
2584    if(U_FAILURE(status)) {
2585        log_err_status(status, "err %s getting calendar values\n", u_errorName(status));
2586    }
2587}
2588
2589static void TestGetFunctionalEquivalentOf(const char *path, const char *resName, const char *keyword, UBool truncate, const char * const testCases[]) {
2590    int32_t i;
2591    for(i=0;testCases[i];i+=3) {
2592        UBool expectAvail = (testCases[i][0]=='t')?TRUE:FALSE;
2593        UBool gotAvail = FALSE;
2594        const char *inLocale = testCases[i+1];
2595        const char *expectLocale = testCases[i+2];
2596        char equivLocale[256];
2597        int32_t len;
2598        UErrorCode status = U_ZERO_ERROR;
2599        log_verbose("%d:   %c      %s\texpect %s\n",i/3,  expectAvail?'t':'f', inLocale, expectLocale);
2600        len = ures_getFunctionalEquivalent(equivLocale, 255, path,
2601            resName, keyword, inLocale,
2602            &gotAvail, truncate, &status);
2603        if(U_FAILURE(status) || (len <= 0)) {
2604            log_err_status(status, "FAIL: got len %d, err %s  on #%d: %c\t%s\t%s\n",
2605                len, u_errorName(status),
2606                i/3,expectAvail?'t':'f', inLocale, expectLocale);
2607        } else {
2608            log_verbose("got:  %c   %s\n", expectAvail?'t':'f',equivLocale);
2609
2610            if((gotAvail != expectAvail) || strcmp(equivLocale, expectLocale)) {
2611                log_err("FAIL: got avail=%c, loc=%s but  expected #%d: %c\t%s\t-> loc=%s\n",
2612                    gotAvail?'t':'f', equivLocale,
2613                    i/3,
2614                    expectAvail?'t':'f', inLocale, expectLocale);
2615
2616            }
2617        }
2618    }
2619}
2620
2621static void TestGetFunctionalEquivalent(void) {
2622#if !UCONFIG_NO_COLLATION
2623    static const char * const collCases[] = {
2624        /*   avail   locale          equiv   */
2625        "f",    "sv_US_CALIFORNIA",               "sv",
2626        "f",    "zh_TW@collation=stroke",         "zh@collation=stroke", /* alias of zh_Hant_TW */
2627        "f",    "zh_Hant_TW@collation=stroke",    "zh@collation=stroke",
2628        "f",    "sv_CN@collation=pinyin",         "sv",
2629        "t",    "zh@collation=pinyin",            "zh",
2630        "f",    "zh_CN@collation=pinyin",         "zh", /* alias of zh_Hans_CN */
2631        "f",    "zh_Hans_CN@collation=pinyin",    "zh",
2632        "f",    "zh_HK@collation=pinyin",         "zh", /* alias of zh_Hant_HK */
2633        "f",    "zh_Hant_HK@collation=pinyin",    "zh",
2634        "f",    "zh_HK@collation=stroke",         "zh@collation=stroke", /* alias of zh_Hant_HK */
2635        "f",    "zh_Hant_HK@collation=stroke",    "zh@collation=stroke",
2636        "f",    "zh_HK",                          "zh@collation=stroke", /* alias of zh_Hant_HK */
2637        "f",    "zh_Hant_HK",                     "zh@collation=stroke",
2638        "f",    "zh_MO",                          "zh@collation=stroke", /* alias of zh_Hant_MO */
2639        "f",    "zh_Hant_MO",                     "zh@collation=stroke",
2640        "f",    "zh_TW_STROKE",                   "zh@collation=stroke",
2641        "f",    "zh_TW_STROKE@collation=pinyin",  "zh",
2642        "f",    "sv_CN@calendar=japanese",        "sv",
2643        "t",    "sv@calendar=japanese",           "sv",
2644        "f",    "zh_TW@collation=pinyin",         "zh", /* alias of zh_Hant_TW */
2645        "f",    "zh_Hant_TW@collation=pinyin",    "zh",
2646        "f",    "zh_CN@collation=stroke",         "zh@collation=stroke", /* alias of zh_Hans_CN */
2647        "f",    "zh_Hans_CN@collation=stroke",    "zh@collation=stroke",
2648        "t",    "de@collation=phonebook",         "de@collation=phonebook",
2649        "t",    "hi@collation=standard",          "hi",
2650        "f",    "hi_AU@collation=standard;currency=CHF;calendar=buddhist",    "hi",
2651        "f",    "sv_SE@collation=pinyin",         "sv", /* bug 4582 tests */
2652        "f",    "sv_SE_BONN@collation=pinyin",    "sv",
2653        "t",    "nl",                             "root",
2654        "f",    "nl_NL",                          "root",
2655        "f",    "nl_NL_EEXT",                     "root",
2656        "t",    "nl@collation=stroke",            "root",
2657        "f",    "nl_NL@collation=stroke",         "root",
2658        "f",    "nl_NL_EEXT@collation=stroke",    "root",
2659        NULL
2660    };
2661#endif  /* !UCONFIG_NO_COLLATION */
2662
2663    static const char *calCases[] = {
2664        /*   avail   locale                       equiv   */
2665        "t",    "en_US_POSIX",                   "en@calendar=gregorian",
2666        "f",    "ja_JP_TOKYO",                   "ja@calendar=gregorian",
2667        "f",    "ja_JP_TOKYO@calendar=japanese", "ja@calendar=japanese",
2668        "t",    "sr@calendar=gregorian", "sr@calendar=gregorian",
2669        "t",    "en", "en@calendar=gregorian",
2670        NULL
2671    };
2672
2673#if !UCONFIG_NO_COLLATION
2674    TestGetFunctionalEquivalentOf(U_ICUDATA_COLL, "collations", "collation", TRUE, collCases);
2675#endif
2676    TestGetFunctionalEquivalentOf("ICUDATA", "calendar", "calendar", FALSE, calCases);
2677
2678#if !UCONFIG_NO_COLLATION
2679    log_verbose("Testing error conditions:\n");
2680    {
2681        char equivLocale[256] = "???";
2682        int32_t len;
2683        UErrorCode status = U_ZERO_ERROR;
2684        UBool gotAvail = FALSE;
2685
2686        len = ures_getFunctionalEquivalent(equivLocale, 255, U_ICUDATA_COLL,
2687            "calendar", "calendar", "ar_EG@calendar=islamic",
2688            &gotAvail, FALSE, &status);
2689        (void)len;    /* Suppress set but not used warning. */
2690
2691        if(status == U_MISSING_RESOURCE_ERROR) {
2692            log_verbose("PASS: Got expected U_MISSING_RESOURCE_ERROR\n");
2693        } else {
2694            log_err("ures_getFunctionalEquivalent  returned locale %s, avail %c, err %s, but expected U_MISSING_RESOURCE_ERROR \n",
2695                equivLocale, gotAvail?'t':'f', u_errorName(status));
2696        }
2697    }
2698#endif
2699}
2700
2701static void TestXPath(void) {
2702    UErrorCode status = U_ZERO_ERROR;
2703    UResourceBundle *rb = NULL, *alias = NULL;
2704    int32_t len = 0;
2705    const UChar* result = NULL;
2706    const UChar expResult[] = { 0x0063, 0x006F, 0x0072, 0x0072, 0x0065, 0x0063, 0x0074, 0x0000 }; /* "correct" */
2707    /*const UChar expResult[] = { 0x0074, 0x0065, 0x0069, 0x006E, 0x0064, 0x0065, 0x0073, 0x0074, 0x0000 }; *//*teindest*/
2708
2709    const char *testdatapath=loadTestData(&status);
2710    if(U_FAILURE(status))
2711    {
2712        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
2713        return;
2714    }
2715
2716    log_verbose("Testing ures_open()......\n");
2717
2718    rb = ures_open(testdatapath, "te_IN", &status);
2719    if(U_FAILURE(status)) {
2720      log_err("Could not open te_IN (%s)\n", myErrorName(status));
2721      return;
2722    }
2723    alias = ures_getByKey(rb, "rootAliasClient", alias, &status);
2724    if(U_FAILURE(status)) {
2725      log_err("Couldn't find the aliased resource (%s)\n", myErrorName(status));
2726      ures_close(rb);
2727      return;
2728    }
2729
2730    result = tres_getString(alias, -1, NULL, &len, &status);
2731    if(U_FAILURE(status) || result == NULL || u_strcmp(result, expResult)) {
2732      log_err("Couldn't get correct string value (%s)\n", myErrorName(status));
2733    }
2734
2735    alias = ures_getByKey(rb, "aliasClient", alias, &status);
2736    if(U_FAILURE(status)) {
2737      log_err("Couldn't find the aliased resource (%s)\n", myErrorName(status));
2738      ures_close(rb);
2739      return;
2740    }
2741
2742    result = tres_getString(alias, -1, NULL, &len, &status);
2743    if(U_FAILURE(status) || result == NULL || u_strcmp(result, expResult)) {
2744      log_err("Couldn't get correct string value (%s)\n", myErrorName(status));
2745    }
2746
2747    alias = ures_getByKey(rb, "nestedRootAliasClient", alias, &status);
2748    if(U_FAILURE(status)) {
2749      log_err("Couldn't find the aliased resource (%s)\n", myErrorName(status));
2750      ures_close(rb);
2751      return;
2752    }
2753
2754    result = tres_getString(alias, -1, NULL, &len, &status);
2755    if(U_FAILURE(status) || result == NULL || u_strcmp(result, expResult)) {
2756      log_err("Couldn't get correct string value (%s)\n", myErrorName(status));
2757    }
2758
2759    ures_close(alias);
2760    ures_close(rb);
2761}
2762static void TestCLDRStyleAliases(void) {
2763    UErrorCode status = U_ZERO_ERROR;
2764    UResourceBundle *rb = NULL, *alias = NULL, *a=NULL;
2765    int32_t i, len;
2766    char resource[256];
2767    const UChar *result = NULL;
2768    UChar expected[256];
2769    const char *expects[7] = { "", "a41", "a12", "a03", "ar4" };
2770    const char *testdatapath=loadTestData(&status);
2771    if(U_FAILURE(status)) {
2772        log_data_err("Could not load testdata.dat %s \n",myErrorName(status));
2773        return;
2774    }
2775    log_verbose("Testing CLDR style aliases......\n");
2776
2777    rb = ures_open(testdatapath, "te_IN_REVISED", &status);
2778    if(U_FAILURE(status)) {
2779      log_err("Could not open te_IN (%s)\n", myErrorName(status));
2780      return;
2781    }
2782    alias = ures_getByKey(rb, "a", alias, &status);
2783    if(U_FAILURE(status)) {
2784      log_err("Couldn't find the aliased with name \"a\" resource (%s)\n", myErrorName(status));
2785      ures_close(rb);
2786      return;
2787    }
2788    for(i = 1; i < 5 ; i++) {
2789      resource[0]='a';
2790      resource[1]='0'+i;
2791      resource[2]=0;
2792      /* instead of sprintf(resource, "a%i", i); */
2793      a = ures_getByKeyWithFallback(alias, resource, a, &status);
2794      result = tres_getString(a, -1, NULL, &len, &status);
2795      u_charsToUChars(expects[i], expected, strlen(expects[i])+1);
2796      if(U_FAILURE(status) || !result || u_strcmp(result, expected)) {
2797        log_err("CLDR style aliases failed resource with name \"%s\" resource, exp %s, got %S (%s)\n", resource, expects[i], result, myErrorName(status));
2798        status = U_ZERO_ERROR;
2799      }
2800    }
2801
2802  ures_close(a);
2803  ures_close(alias);
2804  ures_close(rb);
2805}
2806
2807static void TestFallbackCodes(void) {
2808  UErrorCode status = U_ZERO_ERROR;
2809  const char *testdatapath=loadTestData(&status);
2810
2811  UResourceBundle *res = ures_open(testdatapath, "te_IN", &status);
2812
2813  UResourceBundle *r = NULL, *fall = NULL;
2814
2815  r = ures_getByKey(res, "tagged_array_in_Root_te_te_IN", r, &status);
2816
2817  status = U_ZERO_ERROR;
2818  fall = ures_getByKeyWithFallback(r, "tag2", fall, &status);
2819
2820  if(status != U_ZERO_ERROR) {
2821    log_data_err("Expected error code to be U_ZERO_ERROR, got %s\n", u_errorName(status));
2822    status = U_ZERO_ERROR;
2823  }
2824
2825  fall = ures_getByKeyWithFallback(r, "tag7", fall, &status);
2826
2827  if(status != U_USING_FALLBACK_WARNING) {
2828    log_data_err("Expected error code to be U_USING_FALLBACK_WARNING, got %s\n", u_errorName(status));
2829  }
2830  status = U_ZERO_ERROR;
2831
2832  fall = ures_getByKeyWithFallback(r, "tag1", fall, &status);
2833
2834  if(status != U_USING_DEFAULT_WARNING) {
2835    log_data_err("Expected error code to be U_USING_DEFAULT_WARNING, got %s\n", u_errorName(status));
2836  }
2837  status = U_ZERO_ERROR;
2838
2839  ures_close(fall);
2840  ures_close(r);
2841  ures_close(res);
2842}
2843
2844/* This test will crash if this doesn't work. Results don't need testing. */
2845static void TestStackReuse(void) {
2846    UResourceBundle table;
2847    UErrorCode errorCode = U_ZERO_ERROR;
2848    UResourceBundle *rb = ures_open(NULL, "en_US", &errorCode);
2849
2850    if(U_FAILURE(errorCode)) {
2851        log_data_err("Could not load en_US locale. status=%s\n",myErrorName(errorCode));
2852        return;
2853    }
2854    ures_initStackObject(&table);
2855    ures_getByKeyWithFallback(rb, "Types", &table, &errorCode);
2856    ures_getByKeyWithFallback(&table, "collation", &table, &errorCode);
2857    ures_close(rb);
2858    ures_close(&table);
2859}
2860
2861/* Test ures_getUTF8StringXYZ() --------------------------------------------- */
2862
2863/*
2864 * Replace most ures_getStringXYZ() with this function which wraps the
2865 * desired call and also calls the UTF-8 variant and checks that it works.
2866 */
2867extern const UChar *
2868tres_getString(const UResourceBundle *resB,
2869               int32_t idx, const char *key,
2870               int32_t *length,
2871               UErrorCode *status) {
2872    char buffer8[16];
2873    char *p8;
2874    const UChar *s16;
2875    const char *s8;
2876    UChar32 c16, c8;
2877    int32_t length16, length8, i16, i8;
2878    UBool forceCopy;
2879
2880    if(length == NULL) {
2881        length = &length16;
2882    }
2883    if(idx >= 0) {
2884        s16 = ures_getStringByIndex(resB, idx, length, status);
2885    } else if(key != NULL) {
2886        s16 = ures_getStringByKey(resB, key, length, status);
2887    } else {
2888        s16 = ures_getString(resB, length, status);
2889    }
2890    if(U_FAILURE(*status)) {
2891        return s16;
2892    }
2893    length16 = *length;
2894
2895    /* try the UTF-8 variant of ures_getStringXYZ() */
2896    for(forceCopy = FALSE; forceCopy <= TRUE; ++forceCopy) {
2897        p8 = buffer8;
2898        length8 = (int32_t)sizeof(buffer8);
2899        if(idx >= 0) {
2900            s8 = ures_getUTF8StringByIndex(resB, idx, p8, &length8, forceCopy, status);
2901        } else if(key != NULL) {
2902            s8 = ures_getUTF8StringByKey(resB, key, p8, &length8, forceCopy, status);
2903        } else {
2904            s8 = ures_getUTF8String(resB, p8, &length8, forceCopy, status);
2905        }
2906        if(*status == U_INVALID_CHAR_FOUND) {
2907            /* the UTF-16 string contains an unpaired surrogate, can't test UTF-8 variant */
2908            return s16;
2909        }
2910        if(*status == U_BUFFER_OVERFLOW_ERROR) {
2911            *status = U_ZERO_ERROR;
2912            p8 = (char *)malloc(++length8);
2913            if(p8 == NULL) {
2914                return s16;
2915            }
2916            if(idx >= 0) {
2917                s8 = ures_getUTF8StringByIndex(resB, idx, p8, &length8, forceCopy, status);
2918            } else if(key != NULL) {
2919                s8 = ures_getUTF8StringByKey(resB, key, p8, &length8, forceCopy, status);
2920            } else {
2921                s8 = ures_getUTF8String(resB, p8, &length8, forceCopy, status);
2922            }
2923        }
2924        if(U_FAILURE(*status)) {
2925            /* something unexpected happened */
2926            if(p8 != buffer8) {
2927                free(p8);
2928            }
2929            return s16;
2930        }
2931
2932        if(forceCopy && s8 != p8) {
2933            log_err("ures_getUTF8String(%p, %ld, '%s') did not write the string to dest\n",
2934                    resB, (long)idx, key);
2935        }
2936
2937        /* verify NUL-termination */
2938        if((p8 != buffer8 || length8 < sizeof(buffer8)) && s8[length8] != 0) {
2939            log_err("ures_getUTF8String(%p, %ld, '%s') did not NUL-terminate\n",
2940                    resB, (long)idx, key);
2941        }
2942        /* verify correct string */
2943        i16 = i8 = 0;
2944        while(i16 < length16 && i8 < length8) {
2945            U16_NEXT(s16, i16, length16, c16);
2946            U8_NEXT(s8, i8, length8, c8);
2947            if(c16 != c8) {
2948                log_err("ures_getUTF8String(%p, %ld, '%s') got a bad string, c16=U+%04lx!=U+%04lx=c8 before i16=%ld\n",
2949                        resB, (long)idx, key, (long)c16, (long)c8, (long)i16);
2950            }
2951        }
2952        /* verify correct length */
2953        if(i16 < length16) {
2954            log_err("ures_getUTF8String(%p, %ld, '%s') UTF-8 string too short, length8=%ld, length16=%ld\n",
2955                    resB, (long)idx, key, (long)length8, (long)length16);
2956        }
2957        if(i8 < length8) {
2958            log_err("ures_getUTF8String(%p, %ld, '%s') UTF-8 string too long, length8=%ld, length16=%ld\n",
2959                    resB, (long)idx, key, (long)length8, (long)length16);
2960        }
2961
2962        /* clean up */
2963        if(p8 != buffer8) {
2964            free(p8);
2965        }
2966    }
2967    return s16;
2968}
2969
2970/*
2971 * API tests for ures_getUTF8String().
2972 * Most cases are handled by tres_getString(), which leaves argument checking
2973 * to be tested here.
2974 * Since the variants share most of their implementation, we only need to test
2975 * one of them.
2976 * We also need not test for checking arguments which will be checked by the
2977 * UTF-16 ures_getStringXYZ() that are called internally.
2978 */
2979static void
2980TestGetUTF8String() {
2981    UResourceBundle *res;
2982    const char *testdatapath;
2983    char buffer8[16];
2984    const char *s8;
2985    int32_t length8;
2986    UErrorCode status;
2987
2988    status = U_ZERO_ERROR;
2989    testdatapath = loadTestData(&status);
2990    if(U_FAILURE(status)) {
2991        log_data_err("Could not load testdata.dat - %s\n", u_errorName(status));
2992        return;
2993    }
2994
2995    res = ures_open(testdatapath, "", &status);
2996    if(U_FAILURE(status)) {
2997        log_err("Unable to ures_open(testdata, \"\") - %s\n", u_errorName(status));
2998        return;
2999    }
3000
3001    /* one good call */
3002    status = U_ZERO_ERROR;
3003    length8 = (int32_t)sizeof(buffer8);
3004    s8 = ures_getUTF8StringByKey(res, "string_only_in_Root", buffer8, &length8, FALSE, &status);
3005    (void)s8;    /* Suppress set but not used warning. */
3006    if(status != U_ZERO_ERROR) {
3007        log_err("ures_getUTF8StringByKey(testdata/root string) malfunctioned - %s\n", u_errorName(status));
3008    }
3009
3010    /* negative capacity */
3011    status = U_ZERO_ERROR;
3012    length8 = -1;
3013    s8 = ures_getUTF8StringByKey(res, "string_only_in_Root", buffer8, &length8, FALSE, &status);
3014    if(status != U_ILLEGAL_ARGUMENT_ERROR) {
3015        log_err("ures_getUTF8StringByKey(capacity<0) malfunctioned - %s\n", u_errorName(status));
3016    }
3017
3018    /* capacity>0 but dest=NULL */
3019    status = U_ZERO_ERROR;
3020    length8 = (int32_t)sizeof(buffer8);
3021    s8 = ures_getUTF8StringByKey(res, "string_only_in_Root", NULL, &length8, FALSE, &status);
3022    if(status != U_ILLEGAL_ARGUMENT_ERROR) {
3023        log_err("ures_getUTF8StringByKey(dest=NULL capacity>0) malfunctioned - %s\n", u_errorName(status));
3024    }
3025
3026    ures_close(res);
3027}
3028
3029static void TestCLDRVersion(void) {
3030  UVersionInfo zeroVersion;
3031  UVersionInfo testExpect;
3032  UVersionInfo testCurrent;
3033  UVersionInfo cldrVersion;
3034  char tmp[200];
3035  UErrorCode status = U_ZERO_ERROR;
3036
3037  /* setup the constant value */
3038  u_versionFromString(zeroVersion, "0.0.0.0");
3039
3040  /* test CLDR value from API */
3041  ulocdata_getCLDRVersion(cldrVersion, &status);
3042  if(U_FAILURE(status)) {
3043    /* the show is pretty much over at this point */
3044    log_err_status(status, "FAIL: ulocdata_getCLDRVersion() returned %s\n", u_errorName(status));
3045    return;
3046  } else {
3047    u_versionToString(cldrVersion, tmp);
3048    log_info("ulocdata_getCLDRVersion() returned: '%s'\n", tmp);
3049  }
3050
3051
3052  /* setup from resource bundle */
3053  {
3054    UResourceBundle *res;
3055    const char *testdatapath;
3056
3057    status = U_ZERO_ERROR;
3058    testdatapath = loadTestData(&status);
3059    if(U_FAILURE(status)) {
3060        log_data_err("Could not load testdata.dat - %s\n", u_errorName(status));
3061        return;
3062    }
3063
3064    res = ures_openDirect(testdatapath, "root", &status);
3065    if(U_FAILURE(status)) {
3066        log_err("Unable to ures_open(testdata, \"\") - %s\n", u_errorName(status
3067));
3068        return;
3069    }
3070    ures_getVersionByKey(res, "ExpectCLDRVersionAtLeast", testExpect, &status);
3071    ures_getVersionByKey(res, "CurrentCLDRVersion", testCurrent, &status);
3072    ures_close(res);
3073    if(U_FAILURE(status)) {
3074        log_err("Unable to get test data for CLDR version - %s\n", u_errorName(status));
3075    }
3076  }
3077  if(U_FAILURE(status)) return;
3078
3079
3080  u_versionToString(testExpect,tmp);
3081  log_verbose("(data) ExpectCLDRVersionAtLeast { %s }\n", tmp);
3082  if(memcmp(cldrVersion, testExpect, sizeof(UVersionInfo)) < 0) {
3083    log_data_err("CLDR version is too old, expect at least %s.", tmp);
3084  }
3085  u_versionToString(testCurrent,tmp);
3086  log_verbose("(data) CurrentCLDRVersion { %s }\n", tmp);
3087  switch(memcmp(cldrVersion, testCurrent, sizeof(UVersionInfo))) {
3088    case 0: break; /* OK- current. */
3089    case -1: log_info("CLDR version is behind 'current' (for testdata/root.txt) %s. Some things may fail.\n", tmp); break;
3090    case 1: log_info("CLDR version is ahead of 'current' (for testdata/root.txt) %s. Some things may fail.\n", tmp); break;
3091  }
3092
3093}
3094