• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4  * COPYRIGHT:
5  * Copyright (c) 1997-2016, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  ********************************************************************/
8 /*******************************************************************************
9 *
10 * File CRESTST.C
11 *
12 * Modification History:
13 *        Name                     Description
14 *     Madhu Katragadda            Ported for C API
15 *  06/14/99     stephen           Updated for RB API changes (no suffix).
16 ********************************************************************************
17 */
18 
19 
20 #include "unicode/utypes.h"
21 #include "cintltst.h"
22 #include "unicode/ustring.h"
23 #include "unicode/utf16.h"
24 #include "cmemory.h"
25 #include "cstring.h"
26 #include "filestrm.h"
27 #include <stdlib.h>
28 
29 #define RESTEST_HEAP_CHECK 0
30 
31 #include "unicode/ures.h"
32 #include "crestst.h"
33 #include "unicode/ctest.h"
34 #include "uresimp.h"
35 
36 static void TestOpenDirect(void);
37 static void TestFallback(void);
38 static void TestTable32(void);
39 static void TestFileStream(void);
40 /*****************************************************************************/
41 
42 const UChar kERROR[] = { 0x0045 /*E*/, 0x0052 /*'R'*/, 0x0052 /*'R'*/,
43              0x004F /*'O'*/, 0x0052/*'R'*/, 0x0000 /*'\0'*/};
44 
45 /*****************************************************************************/
46 
47 enum E_Where
48 {
49   e_Root,
50   e_te,
51   e_te_IN,
52   e_Where_count
53 };
54 typedef enum E_Where E_Where;
55 /*****************************************************************************/
56 
57 #define CONFIRM_EQ(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
58     if (u_strcmp(expected,actual)==0) { \
59         record_pass(); \
60     } else { \
61         record_fail(); \
62         log_err("%s  returned  %s  instead of %s\n", action, austrdup(actual), austrdup(expected)); \
63     } \
64 } UPRV_BLOCK_MACRO_END
65 
66 #define CONFIRM_ErrorCode(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
67     if ((expected)==(actual)) { \
68         record_pass(); \
69     } else { \
70         record_fail(); \
71         log_err("%s returned  %s  instead of %s\n", action, myErrorName(actual), myErrorName(expected)); \
72     } \
73 } UPRV_BLOCK_MACRO_END
74 
75 
76 /* Array of our test objects */
77 
78 static struct
79 {
80   const char* name;
81   UErrorCode expected_constructor_status;
82   E_Where where;
83   UBool like[e_Where_count];
84   UBool inherits[e_Where_count];
85 } param[] =
86 {
87   /* "te" means test */
88   /* "IN" means inherits */
89   /* "NE" or "ne" means "does not exist" */
90 
91   { "root",         U_ZERO_ERROR,             e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
92   { "te",           U_ZERO_ERROR,             e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
93   { "te_IN",        U_ZERO_ERROR,             e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
94   { "te_NE",        U_USING_FALLBACK_WARNING, e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
95   { "te_IN_NE",     U_USING_FALLBACK_WARNING, e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
96   { "ne",           U_USING_DEFAULT_WARNING,  e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
97 };
98 
99 static int32_t bundles_count = UPRV_LENGTHOF(param);
100 
101 
102 
103 /***************************************************************************************/
104 
105 /* Array of our test objects */
106 
107 void addResourceBundleTest(TestNode** root);
108 
addResourceBundleTest(TestNode ** root)109 void addResourceBundleTest(TestNode** root)
110 {
111 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
112     addTest(root, &TestConstruction1, "tsutil/crestst/TestConstruction1");
113     addTest(root, &TestOpenDirect, "tsutil/crestst/TestOpenDirect");
114     addTest(root, &TestResourceBundles, "tsutil/crestst/TestResourceBundles");
115     addTest(root, &TestTable32, "tsutil/crestst/TestTable32");
116     addTest(root, &TestFileStream, "tsutil/crestst/TestFileStream");
117     addTest(root, &TestGetSize, "tsutil/crestst/TestGetSize");
118     addTest(root, &TestGetLocaleByType, "tsutil/crestst/TestGetLocaleByType");
119 #endif
120     addTest(root, &TestFallback, "tsutil/crestst/TestFallback");
121     addTest(root, &TestAliasConflict, "tsutil/crestst/TestAliasConflict");
122 
123 }
124 
125 
126 /***************************************************************************************/
TestAliasConflict(void)127 void TestAliasConflict(void) {
128     UErrorCode status = U_ZERO_ERROR;
129     UResourceBundle *he = NULL;
130     UResourceBundle *iw = NULL;
131     const UChar *result = NULL;
132     int32_t resultLen;
133 
134     he = ures_open(NULL, "he", &status);
135     iw = ures_open(NULL, "iw", &status);
136     if(U_FAILURE(status)) {
137         log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
138     }
139     ures_close(iw);
140     result = ures_getStringByKey(he, "ExemplarCharacters", &resultLen, &status);
141     if(U_FAILURE(status) || result == NULL) {
142         log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
143     }
144     ures_close(he);
145 }
146 
147 
TestResourceBundles()148 void TestResourceBundles()
149 {
150     // The test expectation only works if the default locale is not one of the
151     // locale bundle in the testdata which have those info. Therefore, we skip
152     // the test if the default locale is te, sh, mc, or them with subtags.
153     if (    uprv_strncmp(uloc_getDefault(), "te", 2) == 0 ||
154             uprv_strncmp(uloc_getDefault(), "sh", 2) == 0 ||
155             uprv_strncmp(uloc_getDefault(), "mc", 2) == 0) {
156         return;
157     }
158 
159     UErrorCode status = U_ZERO_ERROR;
160     loadTestData(&status);
161     if(U_FAILURE(status)) {
162         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
163         return;
164     }
165 
166     testTag("only_in_Root", TRUE, FALSE, FALSE);
167     testTag("in_Root_te", TRUE, TRUE, FALSE);
168     testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
169     testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
170     testTag("only_in_te", FALSE, TRUE, FALSE);
171     testTag("only_in_te_IN", FALSE, FALSE, TRUE);
172     testTag("in_te_te_IN", FALSE, TRUE, TRUE);
173     testTag("nonexistent", FALSE, FALSE, FALSE);
174 
175     log_verbose("Passed:=  %d   Failed=   %d \n", pass, fail);
176 }
177 
TestConstruction1()178 void TestConstruction1()
179 {
180     UResourceBundle *test1 = 0, *test2 = 0;
181     const UChar *result1, *result2;
182     int32_t resultLen;
183     UChar temp[7];
184 
185     UErrorCode   err = U_ZERO_ERROR;
186     const char* testdatapath ;
187     const char*      locale="te_IN";
188 
189     log_verbose("Testing ures_open()......\n");
190 
191 
192     testdatapath=loadTestData(&err);
193     if(U_FAILURE(err))
194     {
195         log_data_err("Could not load testdata.dat %s \n",myErrorName(err));
196         return;
197     }
198 
199     test1=ures_open(testdatapath, NULL, &err);
200     if(U_FAILURE(err))
201     {
202         log_err("construction of %s did not succeed :  %s \n",NULL, myErrorName(err));
203         return;
204     }
205 
206 
207     test2=ures_open(testdatapath, locale, &err);
208     if(U_FAILURE(err))
209     {
210         log_err("construction of %s did not succeed :  %s \n",locale, myErrorName(err));
211         return;
212     }
213     result1= ures_getStringByKey(test1, "string_in_Root_te_te_IN", &resultLen, &err);
214     result2= ures_getStringByKey(test2, "string_in_Root_te_te_IN", &resultLen, &err);
215 
216 
217     if (U_FAILURE(err)) {
218         log_err("Something threw an error in TestConstruction(): %s\n", myErrorName(err));
219         return;
220     }
221 
222     u_uastrcpy(temp, "TE_IN");
223 
224     if(u_strcmp(result2, temp)!=0)
225     {
226         int n;
227 
228         log_err("Construction test failed for ures_open();\n");
229         if(!getTestOption(VERBOSITY_OPTION))
230             log_info("(run verbose for more information)\n");
231 
232         log_verbose("\nGot->");
233         for(n=0;result2[n];n++)
234         {
235             log_verbose("%04X ",result2[n]);
236         }
237         log_verbose("<\n");
238 
239         log_verbose("\nWant>");
240         for(n=0;temp[n];n++)
241         {
242             log_verbose("%04X ",temp[n]);
243         }
244         log_verbose("<\n");
245 
246     }
247 
248     log_verbose("for string_in_Root_te_te_IN, default.txt had  %s\n", austrdup(result1));
249     log_verbose("for string_in_Root_te_te_IN, te_IN.txt had %s\n", austrdup(result2));
250 
251     /* Test getVersionNumber*/
252     log_verbose("Testing version number\n");
253     log_verbose("for getVersionNumber :  %s\n", ures_getVersionNumber(test1));
254 
255     ures_close(test1);
256     ures_close(test2);
257 }
258 
259 /*****************************************************************************/
260 /*****************************************************************************/
261 
testTag(const char * frag,UBool in_Root,UBool in_te,UBool in_te_IN)262 UBool testTag(const char* frag,
263            UBool in_Root,
264            UBool in_te,
265            UBool in_te_IN)
266 {
267     int32_t passNum=pass;
268 
269     /* Make array from input params */
270 
271     UBool is_in[3];
272     const char *NAME[] = { "ROOT", "TE", "TE_IN" };
273 
274     /* Now try to load the desired items */
275     UResourceBundle* theBundle = NULL;
276     char tag[99];
277     char action[256];
278     UErrorCode status = U_ZERO_ERROR,expected_resource_status = U_ZERO_ERROR;
279     UChar* base = NULL;
280     UChar* expected_string = NULL;
281     const UChar* string = NULL;
282     char item_tag[10];
283     int32_t i,j;
284     int32_t actual_bundle;
285     int32_t resultLen;
286     const char *testdatapath = loadTestData(&status);
287 
288     is_in[0] = in_Root;
289     is_in[1] = in_te;
290     is_in[2] = in_te_IN;
291 
292     strcpy(item_tag, "tag");
293 
294     status = U_ZERO_ERROR;
295     theBundle = ures_open(testdatapath, "root", &status);
296     if(U_FAILURE(status))
297     {
298         ures_close(theBundle);
299         log_err("Couldn't open root bundle in %s", testdatapath);
300         return FALSE;
301     }
302     ures_close(theBundle);
303     theBundle = NULL;
304 
305 
306     for (i=0; i<bundles_count; ++i)
307     {
308         strcpy(action,"construction for");
309         strcat(action, param[i].name);
310 
311 
312         status = U_ZERO_ERROR;
313 
314         theBundle = ures_open(testdatapath, param[i].name, &status);
315         /*theBundle = ures_open("c:\\icu\\icu\\source\\test\\testdata\\testdata", param[i].name, &status);*/
316 
317         CONFIRM_ErrorCode(status,param[i].expected_constructor_status);
318 
319 
320 
321         if(i == 5)
322             actual_bundle = 0; /* ne -> default */
323         else if(i == 3)
324             actual_bundle = 1; /* te_NE -> te */
325         else if(i == 4)
326             actual_bundle = 2; /* te_IN_NE -> te_IN */
327         else
328             actual_bundle = i;
329 
330         expected_resource_status = U_MISSING_RESOURCE_ERROR;
331         for (j=e_te_IN; j>=e_Root; --j)
332         {
333             if (is_in[j] && param[i].inherits[j])
334             {
335 
336                 if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
337                     expected_resource_status = U_ZERO_ERROR;
338                 else if(j == 0)
339                     expected_resource_status = U_USING_DEFAULT_WARNING;
340                 else
341                     expected_resource_status = U_USING_FALLBACK_WARNING;
342 
343                 log_verbose("%s[%d]::%s: in<%d:%s> inherits<%d:%s>.  actual_bundle=%s\n",
344                             param[i].name,
345                             i,
346                             frag,
347                             j,
348                             is_in[j]?"Yes":"No",
349                             j,
350                             param[i].inherits[j]?"Yes":"No",
351                             param[actual_bundle].name);
352 
353                 break;
354             }
355         }
356 
357         for (j=param[i].where; j>=0; --j)
358         {
359             if (is_in[j])
360             {
361                 if(base != NULL) {
362                     free(base);
363                     base = NULL;
364                 }
365 
366                 base=(UChar*)malloc(sizeof(UChar)*(strlen(NAME[j]) + 1));
367                 u_uastrcpy(base,NAME[j]);
368 
369                 break;
370             }
371             else {
372                 if(base != NULL) {
373                     free(base);
374                     base = NULL;
375                 }
376                 base = (UChar*) malloc(sizeof(UChar) * 1);
377                 *base = 0x0000;
378             }
379         }
380 
381         /*-------------------------------------------------------------------- */
382         /* string */
383 
384         strcpy(tag,"string_");
385         strcat(tag,frag);
386 
387         strcpy(action,param[i].name);
388         strcat(action, ".ures_get(" );
389         strcat(action,tag);
390         strcat(action, ")");
391 
392         string=    kERROR;
393 
394         status = U_ZERO_ERROR;
395 
396         ures_getStringByKey(theBundle, tag, &resultLen, &status);
397         if(U_SUCCESS(status))
398         {
399             status = U_ZERO_ERROR;
400             string=ures_getStringByKey(theBundle, tag, &resultLen, &status);
401         }
402 
403         log_verbose("%s got %d, expected %d\n", action, status, expected_resource_status);
404 
405         CONFIRM_ErrorCode(status, expected_resource_status);
406 
407 
408         if(U_SUCCESS(status)){
409             expected_string=(UChar*)malloc(sizeof(UChar)*(u_strlen(base) + 3));
410             u_strcpy(expected_string,base);
411 
412         }
413         else
414         {
415             expected_string = (UChar*)malloc(sizeof(UChar)*(u_strlen(kERROR) + 1));
416             u_strcpy(expected_string,kERROR);
417 
418         }
419 
420         CONFIRM_EQ(string, expected_string);
421 
422         free(expected_string);
423         ures_close(theBundle);
424     }
425     free(base);
426     return (UBool)(passNum == pass);
427 }
428 
record_pass()429 void record_pass()
430 {
431   ++pass;
432 }
433 
record_fail()434 void record_fail()
435 {
436   ++fail;
437 }
438 
439 /**
440  * Test to make sure that the U_USING_FALLBACK_ERROR and U_USING_DEFAULT_ERROR
441  * are set correctly
442  */
443 
TestFallback()444 static void TestFallback()
445 {
446     UErrorCode status = U_ZERO_ERROR;
447     UResourceBundle *fr_FR = NULL;
448     UResourceBundle *subResource = NULL;
449     const UChar *junk; /* ignored */
450     int32_t resultLen;
451 
452     log_verbose("Opening fr_FR..");
453     fr_FR = ures_open(NULL, "fr_FR", &status);
454     if(U_FAILURE(status))
455     {
456         log_err_status(status, "Couldn't open fr_FR - %s\n", u_errorName(status));
457         return;
458     }
459 
460     status = U_ZERO_ERROR;
461 
462 
463     /* clear it out..  just do some calls to get the gears turning */
464     junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
465     (void)junk;    /* Suppress set but not used warning. */
466     status = U_ZERO_ERROR;
467     junk = ures_getStringByKey(fr_FR, "LocaleString", &resultLen, &status);
468     status = U_ZERO_ERROR;
469     junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
470     status = U_ZERO_ERROR;
471 
472     /* OK first one. This should be a Default value. */
473     subResource = ures_getByKey(fr_FR, "layout", NULL, &status);
474     if(status != U_USING_DEFAULT_WARNING)
475     {
476         log_data_err("Expected U_USING_DEFAULT_ERROR when trying to get layout from fr_FR, got %s\n",
477             u_errorName(status));
478     }
479     ures_close(subResource);
480     status = U_ZERO_ERROR;
481 
482     /* and this is a Fallback, to fr */
483     junk = ures_getStringByKey(fr_FR, "ExemplarCharacters", &resultLen, &status);
484     if(status != U_USING_FALLBACK_WARNING)
485     {
486         log_data_err("Expected U_USING_FALLBACK_ERROR when trying to get ExemplarCharacters from fr_FR, got %s\n",
487             u_errorName(status));
488     }
489 
490     status = U_ZERO_ERROR;
491 
492     ures_close(fr_FR);
493 }
494 
495 static void
TestOpenDirect(void)496 TestOpenDirect(void) {
497     UResourceBundle *idna_rules, *casing, *te_IN, *ne, *item, *defaultLocale;
498     UErrorCode errorCode;
499 
500     /*
501      * test that ures_openDirect() opens a resource bundle
502      * where one can look up its own items but not fallback items
503      * from root or similar
504      */
505     errorCode=U_ZERO_ERROR;
506     idna_rules=ures_openDirect(loadTestData(&errorCode), "idna_rules", &errorCode);
507     if(U_FAILURE(errorCode)) {
508         log_data_err("ures_openDirect(\"idna_rules\") failed: %s\n", u_errorName(errorCode));
509         return;
510     }
511 
512     if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
513         log_err("ures_openDirect(\"idna_rules\").getLocale()!=idna_rules\n");
514     }
515     errorCode=U_ZERO_ERROR;
516 
517     /* try an item in idna_rules, must work */
518     item=ures_getByKey(idna_rules, "UnassignedSet", NULL, &errorCode);
519     if(U_FAILURE(errorCode)) {
520         log_err("translit_index.getByKey(local key) failed: %s\n", u_errorName(errorCode));
521         errorCode=U_ZERO_ERROR;
522     } else {
523         ures_close(item);
524     }
525 
526     /* try an item in root, must fail */
527     item=ures_getByKey(idna_rules, "ShortLanguage", NULL, &errorCode);
528     if(U_FAILURE(errorCode)) {
529         errorCode=U_ZERO_ERROR;
530     } else {
531         log_err("idna_rules.getByKey(root key) succeeded!\n");
532         ures_close(item);
533     }
534     ures_close(idna_rules);
535 
536     /* now make sure that "idna_rules" will not work with ures_open() */
537     errorCode=U_ZERO_ERROR;
538     idna_rules=ures_open("testdata", "idna_rules", &errorCode);
539     if(U_FAILURE(errorCode) || errorCode==U_USING_DEFAULT_WARNING || errorCode==U_USING_FALLBACK_WARNING) {
540         /* falling back to default or root is ok */
541         errorCode=U_ZERO_ERROR;
542     } else if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
543         /* Opening this file will work in "files mode" on Windows and the Mac,
544            which have case insensitive file systems */
545         log_err("ures_open(\"idna_rules\") succeeded, should fail! Got: %s\n", u_errorName(errorCode));
546     }
547     ures_close(idna_rules);
548 
549     /* ures_openDirect("translit_index_WronG") must fail */
550     idna_rules=ures_openDirect(NULL, "idna_rules_WronG", &errorCode);
551     if(U_FAILURE(errorCode)) {
552         errorCode=U_ZERO_ERROR;
553     } else {
554         log_err("ures_openDirect(\"idna_rules_WronG\") succeeded, should fail!\n");
555     }
556     ures_close(idna_rules);
557 
558     errorCode = U_USING_FALLBACK_WARNING;
559     idna_rules=ures_openDirect("testdata", "idna_rules", &errorCode);
560     if(U_FAILURE(errorCode)) {
561         log_data_err("ures_openDirect(\"idna_rules\") failed when U_USING_FALLBACK_WARNING was set prior to call: %s\n", u_errorName(errorCode));
562         return;
563     }
564     ures_close(idna_rules);
565 
566     /*
567      * ICU 3.6 has new resource bundle syntax and data for bundles that do not
568      * participate in locale fallback. Now,
569      * - ures_open() works like ures_openDirect() on a bundle with a top-level
570      *   type of ":table(nofallback)" _if_ the bundle exists
571      * - ures_open() will continue to find a root bundle if the requested one
572      *   does not exist, unlike ures_openDirect()
573      *
574      * Test with a different bundle than above to avoid confusion in the cache.
575      */
576 
577     /*
578      * verify that ures_open("casing"), which now has a nofallback declaration,
579      * does not enable fallbacks
580      */
581     errorCode=U_ZERO_ERROR;
582     casing=ures_open("testdata", "casing", &errorCode);
583     if(U_FAILURE(errorCode)) {
584         log_data_err("ures_open(\"casing\") failed: %s\n", u_errorName(errorCode));
585         return;
586     }
587 
588     errorCode=U_ZERO_ERROR;
589     item=ures_getByKey(casing, "Info", NULL, &errorCode);
590     if(U_FAILURE(errorCode)) {
591         log_err("casing.getByKey(Info) failed - %s\n", u_errorName(errorCode));
592     } else {
593         ures_close(item);
594     }
595 
596     errorCode=U_ZERO_ERROR;
597     item=ures_getByKey(casing, "ShortLanguage", NULL, &errorCode);
598     if(U_SUCCESS(errorCode)) {
599         log_err("casing.getByKey(root key) succeeded despite nofallback declaration - %s\n", u_errorName(errorCode));
600         ures_close(item);
601     }
602     ures_close(casing);
603 
604     /*
605      * verify that ures_open("ne") finds the root bundle or default locale
606      * bundle but ures_openDirect("ne") does not.
607      */
608     errorCode=U_ZERO_ERROR;
609     ne=ures_open("testdata", "ne", &errorCode);
610     if(U_FAILURE(errorCode)) {
611         log_data_err("ures_open(\"ne\") failed (expected to get root): %s\n", u_errorName(errorCode));
612     }
613     if(    errorCode!=U_USING_DEFAULT_WARNING ||
614            (0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode)) &&
615             0!=uprv_strcmp(uloc_getDefault(), ures_getLocale(ne, &errorCode)))) {
616         log_err("ures_open(\"ne\") found something other than \"root\" "
617                 "or default locale \"%s\" - %s\n", uloc_getDefault(), u_errorName(errorCode));
618     }
619     ures_close(ne);
620 
621     errorCode=U_ZERO_ERROR;
622     ne=ures_openDirect("testdata", "ne", &errorCode);
623     if(U_SUCCESS(errorCode)) {
624         log_data_err("ures_openDirect(\"ne\") succeeded unexpectedly\n");
625         ures_close(ne);
626     }
627 
628     /* verify that ures_openDirect("te_IN") does not enable fallbacks */
629     errorCode=U_ZERO_ERROR;
630     te_IN=ures_openDirect("testdata", "te_IN", &errorCode);
631     if(U_FAILURE(errorCode)) {
632         log_data_err("ures_open(\"te_IN\") failed: %s\n", u_errorName(errorCode));
633         return;
634     }
635     errorCode=U_ZERO_ERROR;
636     item=ures_getByKey(te_IN, "ShortLanguage", NULL, &errorCode);
637     if(U_SUCCESS(errorCode)) {
638         log_err("te_IN.getByKey(root key) succeeded despite use of ures_openDirect() - %s\n", u_errorName(errorCode));
639         ures_close(item);
640     }
641     ures_close(te_IN);
642 
643     // ICU-21705
644     // Verify that calling ures_openDirect() with a NULL localeID doesn't crash or assert.
645     errorCode = U_ZERO_ERROR;
646     defaultLocale = ures_openDirect(NULL, NULL, &errorCode);
647     ures_close(defaultLocale);
648 }
649 
650 static int32_t
parseTable32Key(const char * key)651 parseTable32Key(const char *key) {
652     int32_t number;
653     char c;
654 
655     number=0;
656     while((c=*key++)!=0) {
657         number<<=1;
658         if(c=='1') {
659             number|=1;
660         }
661     }
662     return number;
663 }
664 
665 static void
TestTable32(void)666 TestTable32(void) {
667     static const struct {
668         const char *key;
669         int32_t number;
670     } testcases[]={
671         { "ooooooooooooooooo", 0 },
672         { "oooooooooooooooo1", 1 },
673         { "ooooooooooooooo1o", 2 },
674         { "oo11ooo1ooo11111o", 25150 },
675         { "oo11ooo1ooo111111", 25151 },
676         { "o1111111111111111", 65535 },
677         { "1oooooooooooooooo", 65536 },
678         { "1ooooooo11o11ooo1", 65969 },
679         { "1ooooooo11o11oo1o", 65970 },
680         { "1ooooooo111oo1111", 65999 }
681     };
682 
683     /* ### TODO UResourceBundle staticItem={ 0 }; - need to know the size */
684     UResourceBundle *res, *item;
685     const UChar *s;
686     const char *key;
687     UErrorCode errorCode;
688     int32_t i, j, number, parsedNumber, length, count;
689 
690     errorCode=U_ZERO_ERROR;
691     res=ures_open(loadTestData(&errorCode), "testtable32", &errorCode);
692     if(U_FAILURE(errorCode)) {
693         log_data_err("unable to open testdata/testtable32.res - %s\n", u_errorName(errorCode));
694         return;
695     }
696     if(ures_getType(res)!=URES_TABLE) {
697         log_data_err("testdata/testtable32.res has type %d instead of URES_TABLE\n", ures_getType(res));
698     }
699 
700     count=ures_getSize(res);
701     if(count!=66000) {
702         log_err("testdata/testtable32.res should have 66000 entries but has %d\n", count);
703     }
704 
705     /* get the items by index */
706     item=NULL;
707     for(i=0; i<count; ++i) {
708         item=ures_getByIndex(res, i, item, &errorCode);
709         if(U_FAILURE(errorCode)) {
710             log_err("unable to get item %d of %d in testdata/testtable32.res - %s\n",
711                     i, count, u_errorName(errorCode));
712             break;
713         }
714 
715         key=ures_getKey(item);
716         parsedNumber=parseTable32Key(key);
717 
718         switch(ures_getType(item)) {
719         case URES_STRING:
720             s=ures_getString(item, &length, &errorCode);
721             if(U_FAILURE(errorCode) || s==NULL) {
722                 log_err("unable to access the string \"%s\" at %d in testdata/testtable32.res - %s\n",
723                         key, i, u_errorName(errorCode));
724                 number=-1;
725             } else {
726                 j=0;
727                 U16_NEXT(s, j, length, number);
728             }
729             break;
730         case URES_INT:
731             number=ures_getInt(item, &errorCode);
732             if(U_FAILURE(errorCode)) {
733                 log_err("unable to access the integer \"%s\" at %d in testdata/testtable32.res - %s\n",
734                         key, i, u_errorName(errorCode));
735                 number=-1;
736             }
737             break;
738         default:
739             log_err("unexpected resource type %d for \"%s\" at %d in testdata/testtable32.res - %s\n",
740                     ures_getType(item), key, i, u_errorName(errorCode));
741             number=-1;
742             break;
743         }
744 
745         if(number>=0 && number!=parsedNumber) {
746             log_err("\"%s\" at %d in testdata/testtable32.res has a string/int value of %d, expected %d\n",
747                     key, i, number, parsedNumber);
748         }
749     }
750 
751     /* search for some items by key */
752     for(i=0; i<UPRV_LENGTHOF(testcases); ++i) {
753         item=ures_getByKey(res, testcases[i].key, item, &errorCode);
754         if(U_FAILURE(errorCode)) {
755             log_err("unable to find the key \"%s\" in testdata/testtable32.res - %s\n",
756                     testcases[i].key, u_errorName(errorCode));
757             continue;
758         }
759 
760         switch(ures_getType(item)) {
761         case URES_STRING:
762             s=ures_getString(item, &length, &errorCode);
763             if(U_FAILURE(errorCode) || s==NULL) {
764                 log_err("unable to access the string \"%s\" in testdata/testtable32.res - %s\n",
765                         testcases[i].key, u_errorName(errorCode));
766                 number=-1;
767             } else {
768                 j=0;
769                 U16_NEXT(s, j, length, number);
770             }
771             break;
772         case URES_INT:
773             number=ures_getInt(item, &errorCode);
774             if(U_FAILURE(errorCode)) {
775                 log_err("unable to access the integer \"%s\" in testdata/testtable32.res - %s\n",
776                         testcases[i].key, u_errorName(errorCode));
777                 number=-1;
778             }
779             break;
780         default:
781             log_err("unexpected resource type %d for \"%s\" in testdata/testtable32.res - %s\n",
782                     ures_getType(item), testcases[i].key, u_errorName(errorCode));
783             number=-1;
784             break;
785         }
786 
787         if(number>=0 && number!=testcases[i].number) {
788             log_err("\"%s\" in testdata/testtable32.res has a string/int value of %d, expected %d\n",
789                     testcases[i].key, number, testcases[i].number);
790         }
791 
792         key=ures_getKey(item);
793         if(0!=uprv_strcmp(key, testcases[i].key)) {
794             log_err("\"%s\" in testdata/testtable32.res claims to have the key \"%s\"\n",
795                     testcases[i].key, key);
796         }
797     }
798 
799     ures_close(item);
800     ures_close(res);
801 }
802 
TestFileStream(void)803 static void TestFileStream(void){
804     int32_t c = 0;
805     int32_t c1=0;
806     UErrorCode status = U_ZERO_ERROR;
807     const char* testdatapath = loadTestData(&status);
808     char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10);
809     FileStream* stream = NULL;
810     /* these should not be closed */
811     FileStream* pStdin  = T_FileStream_stdin();
812     FileStream* pStdout = T_FileStream_stdout();
813     FileStream* pStderr = T_FileStream_stderr();
814 
815     const char* testline = "This is a test line";
816     int32_t bufLen = (int32_t)strlen(testline)+10;
817     char* buf = (char*) malloc(bufLen);
818     int32_t retLen = 0;
819 
820     if(pStdin==NULL){
821         log_err("failed to get T_FileStream_stdin()");
822     }
823     if(pStdout==NULL){
824         log_err("failed to get T_FileStream_stdout()");
825     }
826     if(pStderr==NULL){
827         log_err("failed to get T_FileStream_stderr()");
828     }
829 
830     uprv_strcpy(fileName,testdatapath);
831     uprv_strcat(fileName,".dat");
832     stream = T_FileStream_open(fileName, "r");
833     if(stream==NULL){
834         log_data_err("T_FileStream_open failed to open %s\n",fileName);
835     } else {
836       if(!T_FileStream_file_exists(fileName)){
837         log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName);
838       }
839 
840       retLen=T_FileStream_read(stream,&c,1);
841       if(retLen==0){
842         log_data_err("T_FileStream_read failed to read from %s \n",fileName);
843       }
844       retLen=0;
845       T_FileStream_rewind(stream);
846       T_FileStream_read(stream,&c1,1);
847       if(c!=c1){
848         log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName);
849       }
850       T_FileStream_rewind(stream);
851       c1 = T_FileStream_peek(stream);
852       if(c!=c1){
853         log_data_err("T_FileStream_peek failed to peekd %s \n",fileName);
854       }
855       c = T_FileStream_getc(stream);
856       T_FileStream_ungetc(c,stream);
857       if(c!= T_FileStream_getc(stream)){
858         log_data_err("T_FileStream_ungetc failed to d %s \n",fileName);
859       }
860 
861       if(T_FileStream_size(stream)<=0){
862         log_data_err("T_FileStream_size failed to d %s \n",fileName);
863       }
864       if(T_FileStream_error(stream)){
865         log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName);
866       }
867       if(!T_FileStream_error(NULL)){
868         log_err("T_FileStream_error didn't get an error %s\n",fileName);
869       }
870       T_FileStream_putc(stream, 0x20);
871       if(!T_FileStream_error(stream)){
872         /*
873           Warning
874           writing to a read-only file may not consistently fail on all platforms
875           (e.g. HP-UX, FreeBSD, MacOSX)
876         */
877         log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName);
878       }
879 
880       T_FileStream_close(stream);
881     }
882     /* test writing function */
883     stream=NULL;
884     uprv_strcpy(fileName,testdatapath);
885     uprv_strcat(fileName,".tmp");
886     stream = T_FileStream_open(fileName,"w+");
887 
888     if(stream == NULL){
889         log_data_err("Could not open %s for writing\n",fileName);
890     } else {
891       c= '$';
892       T_FileStream_putc(stream,c);
893       T_FileStream_rewind(stream);
894       if(c != T_FileStream_getc(stream)){
895         log_data_err("T_FileStream_putc failed %s\n",fileName);
896       }
897 
898       T_FileStream_rewind(stream);
899       T_FileStream_writeLine(stream,testline);
900       T_FileStream_rewind(stream);
901       T_FileStream_readLine(stream,buf,bufLen);
902       if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){
903         log_data_err("T_FileStream_writeLine failed %s\n",fileName);
904       }
905 
906       T_FileStream_rewind(stream);
907       T_FileStream_write(stream,testline,(int32_t)strlen(testline));
908       T_FileStream_rewind(stream);
909       retLen = T_FileStream_read(stream, buf, bufLen);
910       if(uprv_strncmp(testline, buf,retLen)!=0){
911         log_data_err("T_FileStream_write failed %s\n",fileName);
912       }
913 
914       T_FileStream_close(stream);
915     }
916     if(!T_FileStream_remove(fileName)){
917         log_data_err("T_FileStream_remove failed to delete %s\n",fileName);
918     }
919 
920 
921     free(fileName);
922     free(buf);
923 
924 }
925 
TestGetSize(void)926 static void TestGetSize(void) {
927     const struct {
928         const char* key;
929         int32_t size;
930     } test[] = {
931         { "zerotest", 1},
932         { "one", 1},
933         { "importtest", 1},
934         { "integerarray", 1},
935         { "emptyarray", 0},
936         { "emptytable", 0},
937         { "emptystring", 1}, /* empty string is still a string */
938         { "emptyint", 1},
939         { "emptybin", 1},
940         { "testinclude", 1},
941         { "collations", 1}, /* not 2 - there is hidden %%CollationBin */
942     };
943 
944     UErrorCode status = U_ZERO_ERROR;
945 
946     UResourceBundle *rb = NULL;
947     UResourceBundle *res = NULL;
948     UResourceBundle *helper = NULL;
949     const char* testdatapath = loadTestData(&status);
950     int32_t i = 0, j = 0;
951     int32_t size = 0;
952 
953     if(U_FAILURE(status))
954     {
955         log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
956         return;
957     }
958 
959     rb = ures_open(testdatapath, "testtypes", &status);
960     if(U_FAILURE(status))
961     {
962         log_err("Could not testtypes resource bundle %s\n", u_errorName(status));
963         return;
964     }
965 
966     for(i = 0; i < UPRV_LENGTHOF(test); i++) {
967         res = ures_getByKey(rb, test[i].key, res, &status);
968         if(U_FAILURE(status))
969         {
970             log_err("Couldn't find the key %s. Error: %s\n", test[i].key, u_errorName(status));
971             ures_close(rb);
972             return;
973         }
974         size = ures_getSize(res);
975         if(size != test[i].size) {
976             log_err("Expected size %i, got size %i for key %s\n", test[i].size, size, test[i].key);
977             for(j = 0; j < size; j++) {
978                 helper = ures_getByIndex(res, j, helper, &status);
979                 log_err("%s\n", ures_getKey(helper));
980             }
981         }
982     }
983     ures_close(helper);
984     ures_close(res);
985     ures_close(rb);
986 }
987 
TestGetLocaleByType(void)988 static void TestGetLocaleByType(void) {
989     static const struct {
990         const char *requestedLocale;
991         const char *resourceKey;
992         const char *validLocale;
993         const char *actualLocale;
994     } test[] = {
995         { "te_IN_BLAH", "string_only_in_te_IN", "te_IN", "te_IN" },
996         { "te_IN_BLAH", "string_only_in_te", "te_IN", "te" },
997         { "te_IN_BLAH", "string_only_in_Root", "te_IN", "root" },
998         { "te_IN_BLAH_01234567890_01234567890_01234567890_01234567890_01234567890_01234567890", "array_2d_only_in_Root", "te_IN", "root" },
999         { "te_IN_BLAH@currency=euro", "array_2d_only_in_te_IN", "te_IN", "te_IN" },
1000         { "te_IN_BLAH@collation=phonebook;calendar=thai", "array_2d_only_in_te", "te_IN", "te" }
1001     };
1002 
1003     UErrorCode status = U_ZERO_ERROR;
1004 
1005     UResourceBundle *rb = NULL;
1006     UResourceBundle *res = NULL;
1007     const char* testdatapath = loadTestData(&status);
1008     int32_t i = 0;
1009     const char *locale = NULL;
1010 
1011     if(U_FAILURE(status))
1012     {
1013         log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
1014         return;
1015     }
1016 
1017     for(i = 0; i < UPRV_LENGTHOF(test); i++) {
1018         rb = ures_open(testdatapath, test[i].requestedLocale, &status);
1019         if(U_FAILURE(status))
1020         {
1021             log_err("Could not open resource bundle %s (error %s)\n", test[i].requestedLocale, u_errorName(status));
1022             status = U_ZERO_ERROR;
1023             continue;
1024         }
1025 
1026         res = ures_getByKey(rb, test[i].resourceKey, res, &status);
1027         if(U_FAILURE(status))
1028         {
1029             log_err("Couldn't find the key %s. Error: %s\n", test[i].resourceKey, u_errorName(status));
1030             ures_close(rb);
1031             status = U_ZERO_ERROR;
1032             continue;
1033         }
1034 
1035         locale = ures_getLocaleByType(res, ULOC_REQUESTED_LOCALE, &status);
1036         if(U_SUCCESS(status) && locale != NULL) {
1037             log_err("Requested locale should return NULL\n");
1038         }
1039         status = U_ZERO_ERROR;
1040         locale = ures_getLocaleByType(res, ULOC_VALID_LOCALE, &status);
1041         if(!locale || strcmp(locale, test[i].validLocale) != 0) {
1042             log_err("Expected valid locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1043         }
1044         locale = ures_getLocaleByType(res, ULOC_ACTUAL_LOCALE, &status);
1045         if(!locale || strcmp(locale, test[i].actualLocale) != 0) {
1046             log_err("Expected actual locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1047         }
1048         ures_close(rb);
1049     }
1050     ures_close(res);
1051 }
1052