Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2010, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 /*****************************************************************************
      7 *
      8 * File CU_CAPITST.C
      9 *
     10 * Modification History:
     11 *        Name                      Description
     12 *     Madhu Katragadda              Ported for C API
     13 ******************************************************************************
     14 */
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 #include <ctype.h>
     19 #include "unicode/uloc.h"
     20 #include "unicode/ucnv.h"
     21 #include "unicode/ucnv_err.h"
     22 #include "unicode/putil.h"
     23 #include "unicode/uset.h"
     24 #include "unicode/ustring.h"
     25 #include "ucnv_bld.h" /* for sizeof(UConverter) */
     26 #include "cmemory.h"  /* for UAlignedMemory */
     27 #include "cintltst.h"
     28 #include "ccapitst.h"
     29 
     30 /* for not including "cstring.h" -begin*/
     31 #ifdef U_WINDOWS
     32 #   define ctest_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE _stricmp(str1, str2)
     33 #elif defined(POSIX)
     34 #   define ctest_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE strcasecmp(str1, str2)
     35 #else
     36 #   define ctest_stricmp(str1, str2) T_CString_stricmp(str1, str2)
     37 #endif
     38 
     39 static int U_EXPORT2
     40 T_CString_stricmp(const char *str1, const char *str2) {
     41     if(str1==NULL) {
     42         if(str2==NULL) {
     43             return 0;
     44         } else {
     45             return -1;
     46         }
     47     } else if(str2==NULL) {
     48         return 1;
     49     } else {
     50         /* compare non-NULL strings lexically with lowercase */
     51         int rc;
     52         unsigned char c1, c2;
     53         for(;;) {
     54             c1=(unsigned char)*str1;
     55             c2=(unsigned char)*str2;
     56             if(c1==0) {
     57                 if(c2==0) {
     58                     return 0;
     59                 } else {
     60                     return -1;
     61                 }
     62             } else if(c2==0) {
     63                 return 1;
     64             } else {
     65                 /* compare non-zero characters with lowercase */
     66                 rc=(int)(unsigned char)tolower(c1)-(int)(unsigned char)tolower(c2);
     67                 if(rc!=0) {
     68                     return rc;
     69                 }
     70             }
     71             ++str1;
     72             ++str2;
     73         }
     74     }
     75 }
     76 /* for not including "cstring.h"  -end*/
     77 
     78 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
     79 
     80 #define NUM_CODEPAGE 1
     81 #define MAX_FILE_LEN 1024*20
     82 #define UCS_FILE_NAME_SIZE 512
     83 
     84 /*returns an action other than the one provided*/
     85 static UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA);
     86 static UConverterToUCallback otherCharAction(UConverterToUCallback MIA);
     87 
     88 static UConverter *
     89 cnv_open(const char *name, UErrorCode *pErrorCode) {
     90     if(name!=NULL && name[0]=='*') {
     91         return ucnv_openPackage(loadTestData(pErrorCode), name+1, pErrorCode);
     92     } else {
     93         return ucnv_open(name, pErrorCode);
     94     }
     95 }
     96 
     97 
     98 static void ListNames(void);
     99 static void TestFlushCache(void);
    100 static void TestDuplicateAlias(void);
    101 static void TestCCSID(void);
    102 static void TestJ932(void);
    103 static void TestJ1968(void);
    104 static void TestLMBCSMaxChar(void);
    105 
    106 #if !UCONFIG_NO_LEGACY_CONVERSION
    107 static void TestConvertSafeCloneCallback(void);
    108 #endif
    109 
    110 static void TestEBCDICSwapLFNL(void);
    111 static void TestConvertEx(void);
    112 static void TestConvertExFromUTF8(void);
    113 static void TestConvertExFromUTF8_C5F0(void);
    114 static void TestConvertAlgorithmic(void);
    115        void TestDefaultConverterError(void);    /* defined in cctest.c */
    116        void TestDefaultConverterSet(void);    /* defined in cctest.c */
    117 static void TestToUCountPending(void);
    118 static void TestFromUCountPending(void);
    119 static void TestDefaultName(void);
    120 static void TestCompareNames(void);
    121 static void TestSubstString(void);
    122 static void InvalidArguments(void);
    123 static void TestGetName(void);
    124 static void TestUTFBOM(void);
    125 
    126 void addTestConvert(TestNode** root);
    127 
    128 void addTestConvert(TestNode** root)
    129 {
    130     addTest(root, &ListNames,                   "tsconv/ccapitst/ListNames");
    131     addTest(root, &TestConvert,                 "tsconv/ccapitst/TestConvert");
    132     addTest(root, &TestFlushCache,              "tsconv/ccapitst/TestFlushCache");
    133     addTest(root, &TestAlias,                   "tsconv/ccapitst/TestAlias");
    134     addTest(root, &TestDuplicateAlias,          "tsconv/ccapitst/TestDuplicateAlias");
    135     addTest(root, &TestConvertSafeClone,        "tsconv/ccapitst/TestConvertSafeClone");
    136 #if !UCONFIG_NO_LEGACY_CONVERSION
    137     addTest(root, &TestConvertSafeCloneCallback,"tsconv/ccapitst/TestConvertSafeCloneCallback");
    138 #endif
    139     addTest(root, &TestCCSID,                   "tsconv/ccapitst/TestCCSID");
    140     addTest(root, &TestJ932,                    "tsconv/ccapitst/TestJ932");
    141     addTest(root, &TestJ1968,                   "tsconv/ccapitst/TestJ1968");
    142 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
    143     addTest(root, &TestLMBCSMaxChar,            "tsconv/ccapitst/TestLMBCSMaxChar");
    144 #endif
    145     addTest(root, &TestEBCDICSwapLFNL,          "tsconv/ccapitst/TestEBCDICSwapLFNL");
    146     addTest(root, &TestConvertEx,               "tsconv/ccapitst/TestConvertEx");
    147     addTest(root, &TestConvertExFromUTF8,       "tsconv/ccapitst/TestConvertExFromUTF8");
    148     addTest(root, &TestConvertExFromUTF8_C5F0,  "tsconv/ccapitst/TestConvertExFromUTF8_C5F0");
    149     addTest(root, &TestConvertAlgorithmic,      "tsconv/ccapitst/TestConvertAlgorithmic");
    150     addTest(root, &TestDefaultConverterError,   "tsconv/ccapitst/TestDefaultConverterError");
    151     addTest(root, &TestDefaultConverterSet,     "tsconv/ccapitst/TestDefaultConverterSet");
    152 #if !UCONFIG_NO_FILE_IO
    153     addTest(root, &TestToUCountPending,         "tsconv/ccapitst/TestToUCountPending");
    154     addTest(root, &TestFromUCountPending,       "tsconv/ccapitst/TestFromUCountPending");
    155 #endif
    156     addTest(root, &TestDefaultName,             "tsconv/ccapitst/TestDefaultName");
    157     addTest(root, &TestCompareNames,            "tsconv/ccapitst/TestCompareNames");
    158     addTest(root, &TestSubstString,             "tsconv/ccapitst/TestSubstString");
    159     addTest(root, &InvalidArguments,            "tsconv/ccapitst/InvalidArguments");
    160     addTest(root, &TestGetName,                 "tsconv/ccapitst/TestGetName");
    161     addTest(root, &TestUTFBOM,                  "tsconv/ccapitst/TestUTFBOM");
    162 }
    163 
    164 static void ListNames(void) {
    165     UErrorCode          err                 =   U_ZERO_ERROR;
    166     int32_t             testLong1           =   0;
    167     const char*            available_conv;
    168     UEnumeration *allNamesEnum = NULL;
    169     int32_t allNamesCount = 0;
    170     uint16_t            count;
    171 
    172     log_verbose("Testing ucnv_openAllNames()...");
    173     allNamesEnum = ucnv_openAllNames(&err);
    174     if(U_FAILURE(err)) {
    175         log_data_err("FAILURE! ucnv_openAllNames() -> %s\n", myErrorName(err));
    176     }
    177     else {
    178         const char *string = NULL;
    179         int32_t len = 0;
    180         int32_t count1 = 0;
    181         int32_t count2 = 0;
    182         allNamesCount = uenum_count(allNamesEnum, &err);
    183         while ((string = uenum_next(allNamesEnum, &len, &err))) {
    184             count1++;
    185             log_verbose("read \"%s\", length %i\n", string, len);
    186         }
    187         if (U_FAILURE(err)) {
    188             log_err("FAILURE! uenum_next(allNamesEnum...) set an error: %s\n", u_errorName(err));
    189             err = U_ZERO_ERROR;
    190         }
    191         uenum_reset(allNamesEnum, &err);
    192         while ((string = uenum_next(allNamesEnum, &len, &err))) {
    193             count2++;
    194             ucnv_close(ucnv_open(string, &err));
    195             log_verbose("read \"%s\", length %i (%s)\n", string, len, U_SUCCESS(err) ? "available" : "unavailable");
    196             err = U_ZERO_ERROR;
    197         }
    198         if (count1 != count2) {
    199             log_err("FAILURE! uenum_reset(allNamesEnum, &err); doesn't work\n");
    200         }
    201     }
    202     uenum_close(allNamesEnum);
    203     err = U_ZERO_ERROR;
    204 
    205     /*Tests ucnv_getAvailableName(), getAvialableCount()*/
    206 
    207     log_verbose("Testing ucnv_countAvailable()...");
    208 
    209     testLong1=ucnv_countAvailable();
    210     log_info("Number of available codepages: %d/%d\n", testLong1, allNamesCount);
    211 
    212     log_verbose("\n---Testing ucnv_getAvailableName..");  /*need to check this out */
    213 
    214     available_conv = ucnv_getAvailableName(testLong1);
    215        /*test ucnv_getAvailableName with err condition*/
    216     log_verbose("\n---Testing ucnv_getAvailableName..with index < 0 ");
    217     available_conv = ucnv_getAvailableName(-1);
    218     if(available_conv != NULL){
    219         log_err("ucnv_getAvailableName() with index < 0) should return NULL\n");
    220     }
    221 
    222     /* Test ucnv_countAliases() etc. */
    223     count = ucnv_countAliases("utf-8", &err);
    224     if(U_FAILURE(err)) {
    225         log_data_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %s\n", myErrorName(err));
    226     } else if(count <= 0) {
    227         log_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %d aliases\n", count);
    228     } else {
    229         /* try to get the aliases individually */
    230         const char *alias;
    231         alias = ucnv_getAlias("utf-8", 0, &err);
    232         if(U_FAILURE(err)) {
    233             log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s\n", myErrorName(err));
    234         } else if(strcmp("UTF-8", alias) != 0) {
    235             log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s instead of UTF-8\n", alias);
    236         } else {
    237             uint16_t aliasNum;
    238             for(aliasNum = 0; aliasNum < count; ++aliasNum) {
    239                 alias = ucnv_getAlias("utf-8", aliasNum, &err);
    240                 if(U_FAILURE(err)) {
    241                     log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", aliasNum, myErrorName(err));
    242                 } else if(strlen(alias) > 20) {
    243                     /* sanity check */
    244                     log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> alias %s insanely long, corrupt?!\n", aliasNum, alias);
    245                 } else {
    246                     log_verbose("alias %d for utf-8: %s\n", aliasNum, alias);
    247                 }
    248             }
    249             if(U_SUCCESS(err)) {
    250                 /* try to fill an array with all aliases */
    251                 const char **aliases;
    252                 aliases=(const char **)malloc(count * sizeof(const char *));
    253                 if(aliases != 0) {
    254                     ucnv_getAliases("utf-8", aliases, &err);
    255                     if(U_FAILURE(err)) {
    256                         log_err("FAILURE! ucnv_getAliases(\"utf-8\") -> %s\n", myErrorName(err));
    257                     } else {
    258                         for(aliasNum = 0; aliasNum < count; ++aliasNum) {
    259                             /* compare the pointers with the ones returned individually */
    260                             alias = ucnv_getAlias("utf-8", aliasNum, &err);
    261                             if(U_FAILURE(err)) {
    262                                 log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", aliasNum, myErrorName(err));
    263                             } else if(aliases[aliasNum] != alias) {
    264                                 log_err("FAILURE! ucnv_getAliases(\"utf-8\")[%d] != ucnv_getAlias(\"utf-8\", %d)\n", aliasNum, aliasNum);
    265                             }
    266                         }
    267                     }
    268                     free((char **)aliases);
    269                 }
    270             }
    271         }
    272     }
    273 }
    274 
    275 
    276 static void TestConvert()
    277 {
    278 #if !UCONFIG_NO_LEGACY_CONVERSION
    279     char                myptr[4];
    280     char                save[4];
    281     int32_t             testLong1           =   0;
    282     uint16_t            rest                =   0;
    283     int32_t             len                 =   0;
    284     int32_t             x                   =   0;
    285     FILE*               ucs_file_in         =   NULL;
    286     UChar                BOM                 =   0x0000;
    287     UChar                myUChar           =   0x0000;
    288     char*               mytarget; /*    [MAX_FILE_LEN] */
    289     char*               mytarget_1;
    290     char*               mytarget_use;
    291     UChar*                consumedUni         =   NULL;
    292     char*               consumed            =   NULL;
    293     char*                 output_cp_buffer; /*    [MAX_FILE_LEN] */
    294     UChar*                ucs_file_buffer; /*    [MAX_FILE_LEN] */
    295     UChar*                ucs_file_buffer_use;
    296     UChar*                my_ucs_file_buffer; /*    [MAX_FILE_LEN] */
    297     UChar*                my_ucs_file_buffer_1;
    298     int8_t                ii                  =   0;
    299     int32_t             j                   =   0;
    300     uint16_t            codepage_index      =   0;
    301     int32_t             cp                  =   0;
    302     UErrorCode          err                 =   U_ZERO_ERROR;
    303     char                ucs_file_name[UCS_FILE_NAME_SIZE];
    304     UConverterFromUCallback          MIA1, MIA1_2;
    305     UConverterToUCallback              MIA2, MIA2_2;
    306     const void         *MIA1Context, *MIA1Context2, *MIA2Context, *MIA2Context2;
    307     UConverter*            someConverters[5];
    308     UConverter*         myConverter = 0;
    309     UChar*                displayname = 0;
    310 
    311     const char* locale;
    312 
    313     UChar* uchar1 = 0;
    314     UChar* uchar2 = 0;
    315     UChar* uchar3 = 0;
    316     int32_t targetcapacity2;
    317     int32_t targetcapacity;
    318     int32_t targetsize;
    319     int32_t disnamelen;
    320 
    321     const UChar* tmp_ucs_buf;
    322     const UChar* tmp_consumedUni=NULL;
    323     const char* tmp_mytarget_use;
    324     const char* tmp_consumed;
    325 
    326     /******************************************************************
    327                                 Checking Unicode -> ksc
    328      ******************************************************************/
    329 
    330     const char*      CodePagesToTest[NUM_CODEPAGE]       =
    331     {
    332        "ibm-949_P110-1999"
    333 
    334 
    335     };
    336     const uint16_t CodePageNumberToTest[NUM_CODEPAGE]             =
    337     {
    338         949
    339     };
    340 
    341 
    342     const int8_t     CodePagesMinChars[NUM_CODEPAGE] =
    343     {
    344         1
    345 
    346     };
    347 
    348     const int8_t     CodePagesMaxChars[NUM_CODEPAGE] =
    349     {
    350         2
    351 
    352     };
    353 
    354     const uint16_t        CodePagesSubstitutionChars[NUM_CODEPAGE]    =
    355     {
    356         0xAFFE
    357     };
    358 
    359     const char* CodePagesTestFiles[NUM_CODEPAGE]    =
    360     {
    361       "uni-text.bin"
    362     };
    363 
    364 
    365     const UConverterPlatform        CodePagesPlatform[NUM_CODEPAGE]    =
    366     {
    367         UCNV_IBM
    368 
    369     };
    370 
    371     const char* CodePagesLocale[NUM_CODEPAGE] =
    372     {
    373         "ko_KR"
    374     };
    375 
    376     UConverterFromUCallback oldFromUAction = NULL;
    377     UConverterToUCallback oldToUAction = NULL;
    378     const void* oldFromUContext = NULL;
    379     const void* oldToUContext = NULL;
    380 
    381     /* Allocate memory */
    382     mytarget = (char*) malloc(MAX_FILE_LEN * sizeof(mytarget[0]));
    383     output_cp_buffer = (char*) malloc(MAX_FILE_LEN * sizeof(output_cp_buffer[0]));
    384     ucs_file_buffer = (UChar*) malloc(MAX_FILE_LEN * sizeof(ucs_file_buffer[0]));
    385     my_ucs_file_buffer = (UChar*) malloc(MAX_FILE_LEN * sizeof(my_ucs_file_buffer[0]));
    386 
    387     ucs_file_buffer_use = ucs_file_buffer;
    388     mytarget_1=mytarget;
    389     mytarget_use        = mytarget;
    390     my_ucs_file_buffer_1=my_ucs_file_buffer;
    391 
    392     /* flush the converter cache to get a consistent state before the flushing is tested */
    393     ucnv_flushCache();
    394 
    395     /*Testing ucnv_openU()*/
    396     {
    397         UChar converterName[]={ 0x0069, 0x0062, 0x006d, 0x002d, 0x0039, 0x0034, 0x0033, 0x0000}; /*ibm-943*/
    398         UChar firstSortedName[]={ 0x0021, 0x0000}; /* ! */
    399         UChar lastSortedName[]={ 0x007E, 0x0000}; /* ~ */
    400         const char *illegalNameChars={ "ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943"};
    401         UChar illegalName[100];
    402         UConverter *converter=NULL;
    403         err=U_ZERO_ERROR;
    404         converter=ucnv_openU(converterName, &err);
    405         if(U_FAILURE(err)){
    406             log_data_err("FAILURE! ucnv_openU(ibm-943, err) failed. %s\n", myErrorName(err));
    407         }
    408         ucnv_close(converter);
    409         err=U_ZERO_ERROR;
    410         converter=ucnv_openU(NULL, &err);
    411         if(U_FAILURE(err)){
    412             log_err("FAILURE! ucnv_openU(NULL, err)  failed. %s\n", myErrorName(err));
    413         }
    414         ucnv_close(converter);
    415         /*testing with error value*/
    416         err=U_ILLEGAL_ARGUMENT_ERROR;
    417         converter=ucnv_openU(converterName, &err);
    418         if(!(converter == NULL)){
    419             log_data_err("FAILURE! ucnv_openU(ibm-943, U_ILLEGAL_ARGUMENT_ERROR) is expected to fail\n");
    420         }
    421         ucnv_close(converter);
    422         err=U_ZERO_ERROR;
    423         u_uastrcpy(illegalName, "");
    424         u_uastrcpy(illegalName, illegalNameChars);
    425         ucnv_openU(illegalName, &err);
    426         if(!(err==U_ILLEGAL_ARGUMENT_ERROR)){
    427             log_err("FAILURE! ucnv_openU(illegalName, err) is expected to fail\n");
    428         }
    429 
    430         err=U_ZERO_ERROR;
    431         ucnv_openU(firstSortedName, &err);
    432         if(err!=U_FILE_ACCESS_ERROR){
    433             log_err("FAILURE! ucnv_openU(firstSortedName, err) is expected to fail\n");
    434         }
    435 
    436         err=U_ZERO_ERROR;
    437         ucnv_openU(lastSortedName, &err);
    438         if(err!=U_FILE_ACCESS_ERROR){
    439             log_err("FAILURE! ucnv_openU(lastSortedName, err) is expected to fail\n");
    440         }
    441 
    442         err=U_ZERO_ERROR;
    443     }
    444     log_verbose("Testing ucnv_open() with converter name greater than 7 characters\n");
    445     {
    446          UConverter *cnv=NULL;
    447          err=U_ZERO_ERROR;
    448          cnv=ucnv_open("ibm-949,Madhu", &err);
    449          if(U_FAILURE(err)){
    450             log_data_err("FAILURE! ucnv_open(\"ibm-949,Madhu\", err)  failed. %s\n", myErrorName(err));
    451          }
    452          ucnv_close(cnv);
    453 
    454     }
    455       /*Testing ucnv_convert()*/
    456     {
    457         int32_t targetLimit=0, sourceLimit=0, i=0, targetCapacity=0;
    458         const uint8_t source[]={ 0x00, 0x04, 0x05, 0x06, 0xa2, 0xb4, 0x00};
    459         const uint8_t expectedTarget[]={ 0x00, 0x37, 0x2d, 0x2e, 0x0e, 0x49, 0x62, 0x0f, 0x00};
    460         char *target=0;
    461         sourceLimit=sizeof(source)/sizeof(source[0]);
    462         err=U_ZERO_ERROR;
    463         targetLimit=0;
    464 
    465         targetCapacity=ucnv_convert("ibm-1364", "ibm-1363", NULL, targetLimit , (const char*)source, sourceLimit, &err);
    466         if(err == U_BUFFER_OVERFLOW_ERROR){
    467             err=U_ZERO_ERROR;
    468             targetLimit=targetCapacity+1;
    469             target=(char*)malloc(sizeof(char) * targetLimit);
    470             targetCapacity=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
    471         }
    472         if(U_FAILURE(err)){
    473             log_data_err("FAILURE! ucnv_convert(ibm-1363->ibm-1364) failed. %s\n", myErrorName(err));
    474         }
    475         else {
    476             for(i=0; i<targetCapacity; i++){
    477                 if(target[i] != expectedTarget[i]){
    478                     log_err("FAIL: ucnv_convert(ibm-1363->ibm-1364) failed.at index \n i=%d,  Expected: %lx Got: %lx\n", i, (UChar)expectedTarget[i], (uint8_t)target[i]);
    479                 }
    480             }
    481 
    482             i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source+1, -1, &err);
    483             if(U_FAILURE(err) || i!=7){
    484                 log_err("FAILURE! ucnv_convert() with sourceLimit=-1 failed: %s, returned %d instead of 7\n",
    485                     u_errorName(err), i);
    486             }
    487 
    488             /*Test error conditions*/
    489             err=U_ZERO_ERROR;
    490             i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, 0, &err);
    491             if(i !=0){
    492                 log_err("FAILURE! ucnv_convert() with sourceLimit=0 is expected to return 0\n");
    493             }
    494 
    495             err=U_ILLEGAL_ARGUMENT_ERROR;
    496             sourceLimit=sizeof(source)/sizeof(source[0]);
    497             i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
    498             if(i !=0 ){
    499                 log_err("FAILURE! ucnv_convert() with err=U_ILLEGAL_ARGUMENT_ERROR is expected to return 0\n");
    500             }
    501 
    502             err=U_ZERO_ERROR;
    503             sourceLimit=sizeof(source)/sizeof(source[0]);
    504             targetLimit=0;
    505             i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
    506             if(!(U_FAILURE(err) && err==U_BUFFER_OVERFLOW_ERROR)){
    507                 log_err("FAILURE! ucnv_convert() with targetLimit=0 is expected to throw U_BUFFER_OVERFLOW_ERROR\n");
    508             }
    509             err=U_ZERO_ERROR;
    510             free(target);
    511         }
    512     }
    513 
    514     /*Testing ucnv_openCCSID and ucnv_open with error conditions*/
    515     log_verbose("\n---Testing ucnv_open with err ! = U_ZERO_ERROR...\n");
    516     err=U_ILLEGAL_ARGUMENT_ERROR;
    517     if(ucnv_open(NULL, &err) != NULL){
    518         log_err("ucnv_open with err != U_ZERO_ERROR is supposed to fail\n");
    519     }
    520     if(ucnv_openCCSID(1051, UCNV_IBM, &err) != NULL){
    521         log_err("ucnv_open with err != U_ZERO_ERROR is supposed to fail\n");
    522     }
    523     err=U_ZERO_ERROR;
    524 
    525     /* Testing ucnv_openCCSID(), ucnv_open(), ucnv_getName() */
    526     log_verbose("\n---Testing ucnv_open default...\n");
    527     someConverters[0] = ucnv_open(NULL,&err);
    528     someConverters[1] = ucnv_open(NULL,&err);
    529     someConverters[2] = ucnv_open("utf8", &err);
    530     someConverters[3] = ucnv_openCCSID(949,UCNV_IBM,&err);
    531     ucnv_close(ucnv_openCCSID(1051, UCNV_IBM, &err)); /* test for j350; ucnv_close(NULL) is safe */
    532     if (U_FAILURE(err)){ log_data_err("FAILURE! %s\n", myErrorName(err));}
    533 
    534     /* Testing ucnv_getName()*/
    535     /*default code page */
    536     ucnv_getName(someConverters[0], &err);
    537     if(U_FAILURE(err)) {
    538         log_data_err("getName[0] failed\n");
    539     } else {
    540         log_verbose("getName(someConverters[0]) returned %s\n", ucnv_getName(someConverters[0], &err));
    541     }
    542     ucnv_getName(someConverters[1], &err);
    543     if(U_FAILURE(err)) {
    544         log_data_err("getName[1] failed\n");
    545     } else {
    546         log_verbose("getName(someConverters[1]) returned %s\n", ucnv_getName(someConverters[1], &err));
    547     }
    548 
    549     ucnv_close(someConverters[0]);
    550     ucnv_close(someConverters[1]);
    551     ucnv_close(someConverters[2]);
    552     ucnv_close(someConverters[3]);
    553 
    554 
    555     for (codepage_index=0; codepage_index <  NUM_CODEPAGE; ++codepage_index)
    556     {
    557         int32_t i = 0;
    558 
    559         err = U_ZERO_ERROR;
    560 #ifdef U_TOPSRCDIR
    561         strcpy(ucs_file_name, U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING);
    562 #else
    563         strcpy(ucs_file_name, loadTestData(&err));
    564 
    565         if(U_FAILURE(err)){
    566             log_err("\nCouldn't get the test data directory... Exiting...Error:%s\n", u_errorName(err));
    567             return;
    568         }
    569 
    570         {
    571             char* index = strrchr(ucs_file_name,(char)U_FILE_SEP_CHAR);
    572 
    573             if((unsigned int)(index-ucs_file_name) != (strlen(ucs_file_name)-1)){
    574                     *(index+1)=0;
    575             }
    576         }
    577 
    578         strcat(ucs_file_name,".."U_FILE_SEP_STRING);
    579 #endif
    580         strcat(ucs_file_name, CodePagesTestFiles[codepage_index]);
    581 
    582         ucs_file_in = fopen(ucs_file_name,"rb");
    583         if (!ucs_file_in)
    584         {
    585             log_data_err("Couldn't open the Unicode file [%s]... Exiting...\n", ucs_file_name);
    586             return;
    587         }
    588 
    589         /*Creates a converter and testing ucnv_openCCSID(u_int code_page, platform, errstatus*/
    590 
    591         /*  myConverter =ucnv_openCCSID(CodePageNumberToTest[codepage_index],UCNV_IBM, &err); */
    592         /*  ucnv_flushCache(); */
    593         myConverter =ucnv_open( "ibm-949", &err);
    594         if (!myConverter || U_FAILURE(err))
    595         {
    596             log_data_err("Error creating the ibm-949 converter - %s \n", u_errorName(err));
    597 
    598             return;
    599         }
    600 
    601         /*testing for ucnv_getName()  */
    602         log_verbose("Testing ucnv_getName()...\n");
    603         ucnv_getName(myConverter, &err);
    604         if(U_FAILURE(err))
    605             log_err("Error in getName\n");
    606         else
    607         {
    608             log_verbose("getName o.k. %s\n", ucnv_getName(myConverter, &err));
    609         }
    610         if (ctest_stricmp(ucnv_getName(myConverter, &err), CodePagesToTest[codepage_index]))
    611             log_err("getName failed\n");
    612         else
    613             log_verbose("getName ok\n");
    614         /*Test getName with error condition*/
    615         {
    616             const char* name=0;
    617             err=U_ILLEGAL_ARGUMENT_ERROR;
    618             log_verbose("Testing ucnv_getName with err != U_ZERO_ERROR");
    619             name=ucnv_getName(myConverter, &err);
    620             if(name != NULL){
    621                 log_err("ucnv_getName() with err != U_ZERO_ERROR is expected to fail");
    622             }
    623             err=U_ZERO_ERROR;
    624         }
    625 
    626 
    627         /*Tests ucnv_getMaxCharSize() and ucnv_getMinCharSize()*/
    628 
    629         log_verbose("Testing ucnv_getMaxCharSize()...\n");
    630         if (ucnv_getMaxCharSize(myConverter)==CodePagesMaxChars[codepage_index])
    631             log_verbose("Max byte per character OK\n");
    632         else
    633             log_err("Max byte per character failed\n");
    634 
    635         log_verbose("\n---Testing ucnv_getMinCharSize()...\n");
    636         if (ucnv_getMinCharSize(myConverter)==CodePagesMinChars[codepage_index])
    637             log_verbose("Min byte per character OK\n");
    638         else
    639             log_err("Min byte per character failed\n");
    640 
    641 
    642         /*Testing for ucnv_getSubstChars() and ucnv_setSubstChars()*/
    643         log_verbose("\n---Testing ucnv_getSubstChars...\n");
    644         ii=4;
    645         ucnv_getSubstChars(myConverter, myptr, &ii, &err);
    646         if (ii <= 0) {
    647             log_err("ucnv_getSubstChars returned a negative number %d\n", ii);
    648         }
    649 
    650         for(x=0;x<ii;x++)
    651             rest = (uint16_t)(((unsigned char)rest << 8) + (unsigned char)myptr[x]);
    652         if (rest==CodePagesSubstitutionChars[codepage_index])
    653             log_verbose("Substitution character ok\n");
    654         else
    655             log_err("Substitution character failed.\n");
    656 
    657         log_verbose("\n---Testing ucnv_setSubstChars RoundTrip Test ...\n");
    658         ucnv_setSubstChars(myConverter, myptr, ii, &err);
    659         if (U_FAILURE(err))
    660         {
    661             log_err("FAILURE! %s\n", myErrorName(err));
    662         }
    663         ucnv_getSubstChars(myConverter,save, &ii, &err);
    664         if (U_FAILURE(err))
    665         {
    666             log_err("FAILURE! %s\n", myErrorName(err));
    667         }
    668 
    669         if (strncmp(save, myptr, ii))
    670             log_err("Saved substitution character failed\n");
    671         else
    672             log_verbose("Saved substitution character ok\n");
    673 
    674         /*Testing for ucnv_getSubstChars() and ucnv_setSubstChars() with error conditions*/
    675         log_verbose("\n---Testing ucnv_getSubstChars.. with len < minBytesPerChar\n");
    676         ii=1;
    677         ucnv_getSubstChars(myConverter, myptr, &ii, &err);
    678         if(err != U_INDEX_OUTOFBOUNDS_ERROR){
    679             log_err("ucnv_getSubstChars() with len < minBytesPerChar should throw U_INDEX_OUTOFBOUNDS_ERROR Got %s\n", myErrorName(err));
    680         }
    681         err=U_ZERO_ERROR;
    682         ii=4;
    683         ucnv_getSubstChars(myConverter, myptr, &ii, &err);
    684         log_verbose("\n---Testing ucnv_setSubstChars.. with len < minBytesPerChar\n");
    685         ucnv_setSubstChars(myConverter, myptr, 0, &err);
    686         if(err != U_ILLEGAL_ARGUMENT_ERROR){
    687             log_err("ucnv_setSubstChars() with len < minBytesPerChar should throw U_ILLEGAL_ARGUMENT_ERROR Got %s\n", myErrorName(err));
    688         }
    689         log_verbose("\n---Testing ucnv_setSubstChars.. with err != U_ZERO_ERROR \n");
    690         strcpy(myptr, "abc");
    691         ucnv_setSubstChars(myConverter, myptr, ii, &err);
    692         err=U_ZERO_ERROR;
    693         ucnv_getSubstChars(myConverter, save, &ii, &err);
    694         if(strncmp(save, myptr, ii) == 0){
    695             log_err("uncv_setSubstChars() with err != U_ZERO_ERROR shouldn't set the SubstChars and just return\n");
    696         }
    697         log_verbose("\n---Testing ucnv_getSubstChars.. with err != U_ZERO_ERROR \n");
    698         err=U_ZERO_ERROR;
    699         strcpy(myptr, "abc");
    700         ucnv_setSubstChars(myConverter, myptr, ii, &err);
    701         err=U_ILLEGAL_ARGUMENT_ERROR;
    702         ucnv_getSubstChars(myConverter, save, &ii, &err);
    703         if(strncmp(save, myptr, ii) == 0){
    704             log_err("uncv_setSubstChars() with err != U_ZERO_ERROR shouldn't fill the SubstChars in the buffer, it just returns\n");
    705         }
    706         err=U_ZERO_ERROR;
    707         /*------*/
    708 
    709 #ifdef U_ENABLE_GENERIC_ISO_2022
    710         /*resetState  ucnv_reset()*/
    711         log_verbose("\n---Testing ucnv_reset()..\n");
    712         ucnv_reset(myConverter);
    713         {
    714              UChar32 c;
    715              const uint8_t in[]={  0x1b, 0x25, 0x42, 0x31, 0x32, 0x61, 0xc0, 0x80, 0xe0, 0x80, 0x80, 0xf0, 0x80, 0x80, 0x80};
    716              const char *source=(const char *)in, *limit=(const char *)in+sizeof(in);
    717              UConverter *cnv=ucnv_open("ISO_2022", &err);
    718              if(U_FAILURE(err)) {
    719                 log_err("Unable to open a iso-2022 converter: %s\n", u_errorName(err));
    720              }
    721              c=ucnv_getNextUChar(cnv, &source, limit, &err);
    722              if((U_FAILURE(err) || c != (UChar32)0x0031)) {
    723                 log_err("ucnv_getNextUChar() failed: %s\n", u_errorName(err));
    724              }
    725              ucnv_reset(cnv);
    726              ucnv_close(cnv);
    727 
    728         }
    729 #endif
    730 
    731         /*getDisplayName*/
    732         log_verbose("\n---Testing ucnv_getDisplayName()...\n");
    733         locale=CodePagesLocale[codepage_index];
    734         len=0;
    735         displayname=NULL;
    736         disnamelen = ucnv_getDisplayName(myConverter, locale, displayname, len, &err);
    737         if(err==U_BUFFER_OVERFLOW_ERROR) {
    738             err=U_ZERO_ERROR;
    739             displayname=(UChar*)malloc((disnamelen+1) * sizeof(UChar));
    740             ucnv_getDisplayName(myConverter,locale,displayname,disnamelen+1, &err);
    741             if(U_FAILURE(err)) {
    742                 log_err("getDisplayName failed. The error is  %s\n", myErrorName(err));
    743             }
    744             else {
    745                 log_verbose(" getDisplayName o.k.\n");
    746             }
    747             free(displayname);
    748             displayname=NULL;
    749         }
    750         else {
    751             log_err("getDisplayName preflight doesn't work. Error is  %s\n", myErrorName(err));
    752         }
    753         /*test ucnv_getDiaplayName with error condition*/
    754         err= U_ILLEGAL_ARGUMENT_ERROR;
    755         len=ucnv_getDisplayName(myConverter,locale,NULL,0, &err);
    756         if( len !=0 ){
    757             log_err("ucnv_getDisplayName() with err != U_ZERO_ERROR is supposed to return 0\n");
    758         }
    759         /*test ucnv_getDiaplayName with error condition*/
    760         err=U_ZERO_ERROR;
    761         len=ucnv_getDisplayName(NULL,locale,NULL,0, &err);
    762         if( len !=0 || U_SUCCESS(err)){
    763             log_err("ucnv_getDisplayName(NULL) with cnv == NULL is supposed to return 0\n");
    764         }
    765         err=U_ZERO_ERROR;
    766 
    767         /* testing ucnv_setFromUCallBack() and ucnv_getFromUCallBack()*/
    768         ucnv_getFromUCallBack(myConverter, &MIA1, &MIA1Context);
    769 
    770         log_verbose("\n---Testing ucnv_setFromUCallBack...\n");
    771         ucnv_setFromUCallBack(myConverter, otherUnicodeAction(MIA1), &BOM, &oldFromUAction, &oldFromUContext, &err);
    772         if (U_FAILURE(err) || oldFromUAction != MIA1 || oldFromUContext != MIA1Context)
    773         {
    774             log_err("FAILURE! %s\n", myErrorName(err));
    775         }
    776 
    777         ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
    778         if (MIA1_2 != otherUnicodeAction(MIA1) || MIA1Context2 != &BOM)
    779             log_err("get From UCallBack failed\n");
    780         else
    781             log_verbose("get From UCallBack ok\n");
    782 
    783         log_verbose("\n---Testing getFromUCallBack Roundtrip...\n");
    784         ucnv_setFromUCallBack(myConverter,MIA1, MIA1Context, &oldFromUAction, &oldFromUContext, &err);
    785         if (U_FAILURE(err) || oldFromUAction != otherUnicodeAction(MIA1) || oldFromUContext != &BOM)
    786         {
    787             log_err("FAILURE! %s\n", myErrorName(err));
    788         }
    789 
    790         ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
    791         if (MIA1_2 != MIA1 || MIA1Context2 != MIA1Context)
    792             log_err("get From UCallBack action failed\n");
    793         else
    794             log_verbose("get From UCallBack action ok\n");
    795 
    796         /*testing ucnv_setToUCallBack with error conditions*/
    797         err=U_ILLEGAL_ARGUMENT_ERROR;
    798         log_verbose("\n---Testing setFromUCallBack. with err != U_ZERO_ERROR..\n");
    799         ucnv_setFromUCallBack(myConverter, otherUnicodeAction(MIA1), &BOM, &oldFromUAction, &oldFromUContext, &err);
    800         ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
    801         if(MIA1_2 == otherUnicodeAction(MIA1) || MIA1Context2 == &BOM){
    802             log_err("To setFromUCallBack with err != U_ZERO_ERROR is supposed to fail\n");
    803         }
    804         err=U_ZERO_ERROR;
    805 
    806 
    807         /*testing ucnv_setToUCallBack() and ucnv_getToUCallBack()*/
    808         ucnv_getToUCallBack(myConverter, &MIA2, &MIA2Context);
    809 
    810         log_verbose("\n---Testing setTo UCallBack...\n");
    811         ucnv_setToUCallBack(myConverter,otherCharAction(MIA2), &BOM, &oldToUAction, &oldToUContext, &err);
    812         if (U_FAILURE(err) || oldToUAction != MIA2 || oldToUContext != MIA2Context)
    813         {
    814             log_err("FAILURE! %s\n", myErrorName(err));
    815         }
    816 
    817         ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
    818         if (MIA2_2 != otherCharAction(MIA2) || MIA2Context2 != &BOM)
    819             log_err("To UCallBack failed\n");
    820         else
    821             log_verbose("To UCallBack ok\n");
    822 
    823         log_verbose("\n---Testing setTo UCallBack Roundtrip...\n");
    824         ucnv_setToUCallBack(myConverter,MIA2, MIA2Context, &oldToUAction, &oldToUContext, &err);
    825         if (U_FAILURE(err) || oldToUAction != otherCharAction(MIA2) || oldToUContext != &BOM)
    826         { log_err("FAILURE! %s\n", myErrorName(err));  }
    827 
    828         ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
    829         if (MIA2_2 != MIA2 || MIA2Context2 != MIA2Context)
    830             log_err("To UCallBack failed\n");
    831         else
    832             log_verbose("To UCallBack ok\n");
    833 
    834         /*testing ucnv_setToUCallBack with error conditions*/
    835         err=U_ILLEGAL_ARGUMENT_ERROR;
    836         log_verbose("\n---Testing setToUCallBack. with err != U_ZERO_ERROR..\n");
    837         ucnv_setToUCallBack(myConverter,otherCharAction(MIA2), NULL, &oldToUAction, &oldToUContext, &err);
    838         ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
    839         if (MIA2_2 == otherCharAction(MIA2) || MIA2Context2 == &BOM){
    840             log_err("To setToUCallBack with err != U_ZERO_ERROR is supposed to fail\n");
    841         }
    842         err=U_ZERO_ERROR;
    843 
    844 
    845         /*getcodepageid testing ucnv_getCCSID() */
    846         log_verbose("\n----Testing getCCSID....\n");
    847         cp =    ucnv_getCCSID(myConverter,&err);
    848         if (U_FAILURE(err))
    849         {
    850             log_err("FAILURE!..... %s\n", myErrorName(err));
    851         }
    852         if (cp != CodePageNumberToTest[codepage_index])
    853             log_err("Codepage number test failed\n");
    854         else
    855             log_verbose("Codepage number test OK\n");
    856 
    857         /*testing ucnv_getCCSID() with err != U_ZERO_ERROR*/
    858         err=U_ILLEGAL_ARGUMENT_ERROR;
    859         if( ucnv_getCCSID(myConverter,&err) != -1){
    860             log_err("ucnv_getCCSID() with err != U_ZERO_ERROR is supposed to fail\n");
    861         }
    862         err=U_ZERO_ERROR;
    863 
    864         /*getCodepagePlatform testing ucnv_getPlatform()*/
    865         log_verbose("\n---Testing getCodepagePlatform ..\n");
    866         if (CodePagesPlatform[codepage_index]!=ucnv_getPlatform(myConverter, &err))
    867             log_err("Platform codepage test failed\n");
    868         else
    869             log_verbose("Platform codepage test ok\n");
    870 
    871         if (U_FAILURE(err))
    872         {
    873             log_err("FAILURE! %s\n", myErrorName(err));
    874         }
    875         /*testing ucnv_getPlatform() with err != U_ZERO_ERROR*/
    876         err= U_ILLEGAL_ARGUMENT_ERROR;
    877         if(ucnv_getPlatform(myConverter, &err) != UCNV_UNKNOWN){
    878             log_err("ucnv)getPlatform with err != U_ZERO_ERROR is supposed to fail\n");
    879         }
    880         err=U_ZERO_ERROR;
    881 
    882 
    883         /*Reads the BOM*/
    884         fread(&BOM, sizeof(UChar), 1, ucs_file_in);
    885         if (BOM!=0xFEFF && BOM!=0xFFFE)
    886         {
    887             log_err("File Missing BOM...Bailing!\n");
    888             return;
    889         }
    890 
    891 
    892         /*Reads in the file*/
    893         while(!feof(ucs_file_in)&&(i+=fread(ucs_file_buffer+i, sizeof(UChar), 1, ucs_file_in)))
    894         {
    895             myUChar = ucs_file_buffer[i-1];
    896 
    897             ucs_file_buffer[i-1] = (UChar)((BOM==0xFEFF)?myUChar:((myUChar >> 8) | (myUChar << 8))); /*adjust if BIG_ENDIAN*/
    898         }
    899 
    900         myUChar = ucs_file_buffer[i-1];
    901         ucs_file_buffer[i-1] = (UChar)((BOM==0xFEFF)?myUChar:((myUChar >> 8) | (myUChar << 8))); /*adjust if BIG_ENDIAN Corner Case*/
    902 
    903 
    904         /*testing ucnv_fromUChars() and ucnv_toUChars() */
    905         /*uchar1---fromUChar--->output_cp_buffer --toUChar--->uchar2*/
    906 
    907         uchar1=(UChar*)malloc(sizeof(UChar) * (i+1));
    908         u_uastrcpy(uchar1,"");
    909         u_strncpy(uchar1,ucs_file_buffer,i);
    910         uchar1[i] = 0;
    911 
    912         uchar3=(UChar*)malloc(sizeof(UChar)*(i+1));
    913         u_uastrcpy(uchar3,"");
    914         u_strncpy(uchar3,ucs_file_buffer,i);
    915         uchar3[i] = 0;
    916 
    917         /*Calls the Conversion Routine */
    918         testLong1 = MAX_FILE_LEN;
    919         log_verbose("\n---Testing ucnv_fromUChars()\n");
    920         targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1,  uchar1, -1, &err);
    921         if (U_FAILURE(err))
    922         {
    923             log_err("\nFAILURE...%s\n", myErrorName(err));
    924         }
    925         else
    926             log_verbose(" ucnv_fromUChars() o.k.\n");
    927 
    928         /*test the conversion routine */
    929         log_verbose("\n---Testing ucnv_toUChars()\n");
    930         /*call it first time for trapping the targetcapacity and size needed to allocate memory for the buffer uchar2 */
    931         targetcapacity2=0;
    932         targetsize = ucnv_toUChars(myConverter,
    933                      NULL,
    934                      targetcapacity2,
    935                      output_cp_buffer,
    936                      strlen(output_cp_buffer),
    937                      &err);
    938         /*if there is an buffer overflow then trap the values and pass them and make the actual call*/
    939 
    940         if(err==U_BUFFER_OVERFLOW_ERROR)
    941         {
    942             err=U_ZERO_ERROR;
    943             uchar2=(UChar*)malloc((targetsize+1) * sizeof(UChar));
    944             targetsize = ucnv_toUChars(myConverter,
    945                    uchar2,
    946                    targetsize+1,
    947                    output_cp_buffer,
    948                    strlen(output_cp_buffer),
    949                    &err);
    950 
    951             if(U_FAILURE(err))
    952                 log_err("ucnv_toUChars() FAILED %s\n", myErrorName(err));
    953             else
    954                 log_verbose(" ucnv_toUChars() o.k.\n");
    955 
    956             if(u_strcmp(uchar1,uchar2)!=0)
    957                 log_err("equality test failed with conversion routine\n");
    958         }
    959         else
    960         {
    961             log_err("ERR: calling toUChars: Didn't get U_BUFFER_OVERFLOW .. expected it.\n");
    962         }
    963         /*Testing ucnv_fromUChars and ucnv_toUChars with error conditions*/
    964         err=U_ILLEGAL_ARGUMENT_ERROR;
    965         log_verbose("\n---Testing ucnv_fromUChars() with err != U_ZERO_ERROR\n");
    966         targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1,  uchar1, -1, &err);
    967         if (targetcapacity !=0) {
    968             log_err("\nFAILURE: ucnv_fromUChars with err != U_ZERO_ERROR is expected to fail and return 0\n");
    969         }
    970         err=U_ZERO_ERROR;
    971         log_verbose("\n---Testing ucnv_fromUChars() with converter=NULL\n");
    972         targetcapacity = ucnv_fromUChars(NULL, output_cp_buffer, testLong1,  uchar1, -1, &err);
    973         if (targetcapacity !=0 || err != U_ILLEGAL_ARGUMENT_ERROR) {
    974             log_err("\nFAILURE: ucnv_fromUChars with converter=NULL is expected to fail\n");
    975         }
    976         err=U_ZERO_ERROR;
    977         log_verbose("\n---Testing ucnv_fromUChars() with sourceLength = 0\n");
    978         targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1,  uchar1, 0, &err);
    979         if (targetcapacity !=0) {
    980             log_err("\nFAILURE: ucnv_fromUChars with sourceLength 0 is expected to return 0\n");
    981         }
    982         log_verbose("\n---Testing ucnv_fromUChars() with targetLength = 0\n");
    983         targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, 0,  uchar1, -1, &err);
    984         if (err != U_BUFFER_OVERFLOW_ERROR) {
    985             log_err("\nFAILURE: ucnv_fromUChars with targetLength 0 is expected to fail and throw U_BUFFER_OVERFLOW_ERROR\n");
    986         }
    987         /*toUChars with error conditions*/
    988         targetsize = ucnv_toUChars(myConverter, uchar2, targetsize, output_cp_buffer, strlen(output_cp_buffer), &err);
    989         if(targetsize != 0){
    990             log_err("\nFAILURE: ucnv_toUChars with err != U_ZERO_ERROR is expected to fail and return 0\n");
    991         }
    992         err=U_ZERO_ERROR;
    993         targetsize = ucnv_toUChars(myConverter, uchar2, -1, output_cp_buffer, strlen(output_cp_buffer), &err);
    994         if(targetsize != 0 || err != U_ILLEGAL_ARGUMENT_ERROR){
    995             log_err("\nFAILURE: ucnv_toUChars with targetsize < 0 is expected to throw U_ILLEGAL_ARGUMENT_ERROR and return 0\n");
    996         }
    997         err=U_ZERO_ERROR;
    998         targetsize = ucnv_toUChars(myConverter, uchar2, 0, output_cp_buffer, 0, &err);
    999         if (targetsize !=0) {
   1000             log_err("\nFAILURE: ucnv_toUChars with sourceLength 0 is expected to return 0\n");
   1001         }
   1002         targetcapacity2=0;
   1003         targetsize = ucnv_toUChars(myConverter, NULL, targetcapacity2, output_cp_buffer,  strlen(output_cp_buffer), &err);
   1004         if (err != U_STRING_NOT_TERMINATED_WARNING) {
   1005             log_err("\nFAILURE: ucnv_toUChars(targetLength)->%s instead of U_STRING_NOT_TERMINATED_WARNING\n",
   1006                     u_errorName(err));
   1007         }
   1008         err=U_ZERO_ERROR;
   1009         /*-----*/
   1010 
   1011 
   1012         /*testing for ucnv_fromUnicode() and ucnv_toUnicode() */
   1013         /*Clean up re-usable vars*/
   1014         j=0;
   1015         log_verbose("Testing ucnv_fromUnicode().....\n");
   1016         tmp_ucs_buf=ucs_file_buffer_use;
   1017         ucnv_fromUnicode(myConverter, &mytarget_1,
   1018                  mytarget + MAX_FILE_LEN,
   1019                  &tmp_ucs_buf,
   1020                  ucs_file_buffer_use+i,
   1021                  NULL,
   1022                  TRUE,
   1023                  &err);
   1024         consumedUni = (UChar*)tmp_consumedUni;
   1025 
   1026         if (U_FAILURE(err))
   1027         {
   1028             log_err("FAILURE! %s\n", myErrorName(err));
   1029         }
   1030         else
   1031             log_verbose("ucnv_fromUnicode()   o.k.\n");
   1032 
   1033         /*Uni1 ----ToUnicode----> Cp2 ----FromUnicode---->Uni3 */
   1034         log_verbose("Testing ucnv_toUnicode().....\n");
   1035         tmp_mytarget_use=mytarget_use;
   1036         tmp_consumed = consumed;
   1037         ucnv_toUnicode(myConverter, &my_ucs_file_buffer_1,
   1038                 my_ucs_file_buffer + MAX_FILE_LEN,
   1039                 &tmp_mytarget_use,
   1040                 mytarget_use + (mytarget_1 - mytarget),
   1041                 NULL,
   1042                 FALSE,
   1043                 &err);
   1044         consumed = (char*)tmp_consumed;
   1045         if (U_FAILURE(err))
   1046         {
   1047             log_err("FAILURE! %s\n", myErrorName(err));
   1048         }
   1049         else
   1050             log_verbose("ucnv_toUnicode()  o.k.\n");
   1051 
   1052 
   1053         log_verbose("\n---Testing   RoundTrip ...\n");
   1054 
   1055 
   1056         u_strncpy(uchar3, my_ucs_file_buffer,i);
   1057         uchar3[i] = 0;
   1058 
   1059         if(u_strcmp(uchar1,uchar3)==0)
   1060             log_verbose("Equality test o.k.\n");
   1061         else
   1062             log_err("Equality test failed\n");
   1063 
   1064         /*sanity compare */
   1065         if(uchar2 == NULL)
   1066         {
   1067             log_err("uchar2 was NULL (ccapitst.c line %d), couldn't do sanity check\n", __LINE__);
   1068         }
   1069         else
   1070         {
   1071             if(u_strcmp(uchar2, uchar3)==0)
   1072                 log_verbose("Equality test o.k.\n");
   1073             else
   1074                 log_err("Equality test failed\n");
   1075         }
   1076 
   1077         fclose(ucs_file_in);
   1078         ucnv_close(myConverter);
   1079         if (uchar1 != 0) free(uchar1);
   1080         if (uchar2 != 0) free(uchar2);
   1081         if (uchar3 != 0) free(uchar3);
   1082     }
   1083 
   1084     free((void*)mytarget);
   1085     free((void*)output_cp_buffer);
   1086     free((void*)ucs_file_buffer);
   1087     free((void*)my_ucs_file_buffer);
   1088 #endif
   1089 }
   1090 
   1091 static UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA)
   1092 {
   1093     return (MIA==(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP)?(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_SUBSTITUTE:(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP;
   1094 }
   1095 
   1096 
   1097 static UConverterToUCallback otherCharAction(UConverterToUCallback MIA)
   1098 {
   1099     return (MIA==(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP)?(UConverterToUCallback)UCNV_TO_U_CALLBACK_SUBSTITUTE:(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP;
   1100 }
   1101 
   1102 static void TestFlushCache(void) {
   1103 #if !UCONFIG_NO_LEGACY_CONVERSION
   1104     UErrorCode          err                 =   U_ZERO_ERROR;
   1105     UConverter*            someConverters[5];
   1106     int flushCount = 0;
   1107 
   1108     /* flush the converter cache to get a consistent state before the flushing is tested */
   1109     ucnv_flushCache();
   1110 
   1111     /*Testing ucnv_open()*/
   1112     /* Note: These converters have been chosen because they do NOT
   1113        encode the Latin characters (U+0041, ...), and therefore are
   1114        highly unlikely to be chosen as system default codepages */
   1115 
   1116     someConverters[0] = ucnv_open("ibm-1047", &err);
   1117     if (U_FAILURE(err)) {
   1118         log_data_err("FAILURE! %s\n", myErrorName(err));
   1119     }
   1120 
   1121     someConverters[1] = ucnv_open("ibm-1047", &err);
   1122     if (U_FAILURE(err)) {
   1123         log_data_err("FAILURE! %s\n", myErrorName(err));
   1124     }
   1125 
   1126     someConverters[2] = ucnv_open("ibm-1047", &err);
   1127     if (U_FAILURE(err)) {
   1128         log_data_err("FAILURE! %s\n", myErrorName(err));
   1129     }
   1130 
   1131     someConverters[3] = ucnv_open("gb18030", &err);
   1132     if (U_FAILURE(err)) {
   1133         log_data_err("FAILURE! %s\n", myErrorName(err));
   1134     }
   1135 
   1136     someConverters[4] = ucnv_open("ibm-954", &err);
   1137     if (U_FAILURE(err)) {
   1138         log_data_err("FAILURE! %s\n", myErrorName(err));
   1139     }
   1140 
   1141 
   1142     /* Testing ucnv_flushCache() */
   1143     log_verbose("\n---Testing ucnv_flushCache...\n");
   1144     if ((flushCount=ucnv_flushCache())==0)
   1145         log_verbose("Flush cache ok\n");
   1146     else
   1147         log_data_err("Flush Cache failed [line %d], expect 0 got %d \n", __LINE__, flushCount);
   1148 
   1149     /*testing ucnv_close() and ucnv_flushCache() */
   1150     ucnv_close(someConverters[0]);
   1151     ucnv_close(someConverters[1]);
   1152 
   1153     if ((flushCount=ucnv_flushCache())==0)
   1154         log_verbose("Flush cache ok\n");
   1155     else
   1156         log_data_err("Flush Cache failed [line %d], expect 0 got %d \n", __LINE__, flushCount);
   1157 
   1158     ucnv_close(someConverters[2]);
   1159     ucnv_close(someConverters[3]);
   1160 
   1161     if ((flushCount=ucnv_flushCache())==2)
   1162         log_verbose("Flush cache ok\n");  /*because first, second and third are same  */
   1163     else
   1164         log_data_err("Flush Cache failed  line %d, got %d expected 2 or there is an error in ucnv_close()\n",
   1165             __LINE__,
   1166             flushCount);
   1167 
   1168     ucnv_close(someConverters[4]);
   1169     if ( (flushCount=ucnv_flushCache())==1)
   1170         log_verbose("Flush cache ok\n");
   1171     else
   1172         log_data_err("Flush Cache failed line %d, expected 1 got %d \n", __LINE__, flushCount);
   1173 #endif
   1174 }
   1175 
   1176 /**
   1177  * Test the converter alias API, specifically the fuzzy matching of
   1178  * alias names and the alias table integrity.  Make sure each
   1179  * converter has at least one alias (itself), and that its listed
   1180  * aliases map back to itself.  Check some hard-coded UTF-8 and
   1181  * ISO_2022 aliases to make sure they work.
   1182  */
   1183 static void TestAlias() {
   1184     int32_t i, ncnv;
   1185     UErrorCode status = U_ZERO_ERROR;
   1186 
   1187     /* Predetermined aliases that we expect to map back to ISO_2022
   1188      * and UTF-8.  UPDATE THIS DATA AS NECESSARY. */
   1189     const char* ISO_2022_NAMES[] =
   1190         {"ISO_2022,locale=ja,version=2", "ISO-2022-JP-2", "csISO2022JP2",
   1191          "Iso-2022jP2", "isO-2022_Jp_2", "iSo--2022,locale=ja,version=2"};
   1192     int32_t ISO_2022_NAMES_LENGTH =
   1193         sizeof(ISO_2022_NAMES) / sizeof(ISO_2022_NAMES[0]);
   1194     const char *UTF8_NAMES[] =
   1195         { "UTF-8", "utf-8", "utf8", "ibm-1208",
   1196           "utf_8", "ibm1208", "cp1208" };
   1197     int32_t UTF8_NAMES_LENGTH =
   1198         sizeof(UTF8_NAMES) / sizeof(UTF8_NAMES[0]);
   1199 
   1200     struct {
   1201         const char *name;
   1202         const char *alias;
   1203     } CONVERTERS_NAMES[] = {
   1204         { "UTF-32BE", "UTF32_BigEndian" },
   1205         { "UTF-32LE", "UTF32_LittleEndian" },
   1206         { "UTF-32",   "ISO-10646-UCS-4" },
   1207         { "UTF32_PlatformEndian", "UTF32_PlatformEndian" },
   1208         { "UTF-32",   "ucs-4" }
   1209     };
   1210     int32_t CONVERTERS_NAMES_LENGTH = sizeof(CONVERTERS_NAMES) / sizeof(*CONVERTERS_NAMES);
   1211 
   1212     /* When there are bugs in gencnval or in ucnv_io, converters can
   1213        appear to have no aliases. */
   1214     ncnv = ucnv_countAvailable();
   1215     log_verbose("%d converters\n", ncnv);
   1216     for (i=0; i<ncnv; ++i) {
   1217         const char *name = ucnv_getAvailableName(i);
   1218         const char *alias0;
   1219         uint16_t na = ucnv_countAliases(name, &status);
   1220         uint16_t j;
   1221         UConverter *cnv;
   1222 
   1223         if (na == 0) {
   1224             log_err("FAIL: Converter \"%s\" (i=%d)"
   1225                     " has no aliases; expect at least one\n",
   1226                     name, i);
   1227             continue;
   1228         }
   1229         cnv = ucnv_open(name, &status);
   1230         if (U_FAILURE(status)) {
   1231             log_data_err("FAIL: Converter \"%s\" (i=%d)"
   1232                     " can't be opened.\n",
   1233                     name, i);
   1234         }
   1235         else {
   1236             if (strcmp(ucnv_getName(cnv, &status), name) != 0
   1237                 && (strstr(name, "PlatformEndian") == 0 && strstr(name, "OppositeEndian") == 0)) {
   1238                 log_err("FAIL: Converter \"%s\" returned \"%s\" for getName. "
   1239                         "The should be the same\n",
   1240                         name, ucnv_getName(cnv, &status));
   1241             }
   1242         }
   1243         ucnv_close(cnv);
   1244 
   1245         status = U_ZERO_ERROR;
   1246         alias0 = ucnv_getAlias(name, 0, &status);
   1247         for (j=1; j<na; ++j) {
   1248             const char *alias;
   1249             /* Make sure each alias maps back to the the same list of
   1250                aliases.  Assume that if alias 0 is the same, the whole
   1251                list is the same (this should always be true). */
   1252             const char *mapBack;
   1253 
   1254             status = U_ZERO_ERROR;
   1255             alias = ucnv_getAlias(name, j, &status);
   1256             if (status == U_AMBIGUOUS_ALIAS_WARNING) {
   1257                 log_err("FAIL: Converter \"%s\"is ambiguous\n", name);
   1258             }
   1259 
   1260             if (alias == NULL) {
   1261                 log_err("FAIL: Converter \"%s\" -> "
   1262                         "alias[%d]=NULL\n",
   1263                         name, j);
   1264                 continue;
   1265             }
   1266 
   1267             mapBack = ucnv_getAlias(alias, 0, &status);
   1268 
   1269             if (mapBack == NULL) {
   1270                 log_err("FAIL: Converter \"%s\" -> "
   1271                         "alias[%d]=\"%s\" -> "
   1272                         "alias[0]=NULL, exp. \"%s\"\n",
   1273                         name, j, alias, alias0);
   1274                 continue;
   1275             }
   1276 
   1277             if (0 != strcmp(alias0, mapBack)) {
   1278                 int32_t idx;
   1279                 UBool foundAlias = FALSE;
   1280                 if (status == U_AMBIGUOUS_ALIAS_WARNING) {
   1281                     /* Make sure that we only get this mismapping when there is
   1282                        an ambiguous alias, and the other converter has this alias too. */
   1283                     for (idx = 0; idx < ucnv_countAliases(mapBack, &status); idx++) {
   1284                         if (strcmp(ucnv_getAlias(mapBack, (uint16_t)idx, &status), alias) == 0) {
   1285                             foundAlias = TRUE;
   1286                             break;
   1287                         }
   1288                     }
   1289                 }
   1290                 /* else not ambiguous, and this is a real problem. foundAlias = FALSE */
   1291 
   1292                 if (!foundAlias) {
   1293                     log_err("FAIL: Converter \"%s\" -> "
   1294                             "alias[%d]=\"%s\" -> "
   1295                             "alias[0]=\"%s\", exp. \"%s\"\n",
   1296                             name, j, alias, mapBack, alias0);
   1297                 }
   1298             }
   1299         }
   1300     }
   1301 
   1302 
   1303     /* Check a list of predetermined aliases that we expect to map
   1304      * back to ISO_2022 and UTF-8. */
   1305     for (i=1; i<ISO_2022_NAMES_LENGTH; ++i) {
   1306         const char* mapBack = ucnv_getAlias(ISO_2022_NAMES[i], 0, &status);
   1307         if(!mapBack) {
   1308           log_data_err("Couldn't get alias for %s. You probably have no data\n", ISO_2022_NAMES[i]);
   1309           continue;
   1310         }
   1311         if (0 != strcmp(mapBack, ISO_2022_NAMES[0])) {
   1312             log_err("FAIL: \"%s\" -> \"%s\", expect \"ISO_2022,locale=ja,version=2\"\n",
   1313                     ISO_2022_NAMES[i], mapBack);
   1314         }
   1315     }
   1316 
   1317 
   1318     for (i=1; i<UTF8_NAMES_LENGTH; ++i) {
   1319         const char* mapBack = ucnv_getAlias(UTF8_NAMES[i], 0, &status);
   1320         if(!mapBack) {
   1321           log_data_err("Couldn't get alias for %s. You probably have no data\n", UTF8_NAMES[i]);
   1322           continue;
   1323         }
   1324         if (mapBack && 0 != strcmp(mapBack, UTF8_NAMES[0])) {
   1325             log_err("FAIL: \"%s\" -> \"%s\", expect UTF-8\n",
   1326                     UTF8_NAMES[i], mapBack);
   1327         }
   1328     }
   1329 
   1330     /*
   1331      * Check a list of predetermined aliases that we expect to map
   1332      * back to predermined converter names.
   1333      */
   1334 
   1335     for (i = 0; i < CONVERTERS_NAMES_LENGTH; ++i) {
   1336         const char* mapBack = ucnv_getAlias(CONVERTERS_NAMES[i].alias, 0, &status);
   1337         if(!mapBack) {
   1338           log_data_err("Couldn't get alias for %s. You probably have no data\n", CONVERTERS_NAMES[i].name);
   1339           continue;
   1340         }
   1341         if (0 != strcmp(mapBack, CONVERTERS_NAMES[i].name)) {
   1342             log_err("FAIL: \"%s\" -> \"%s\", expect %s\n",
   1343                     CONVERTERS_NAMES[i].alias, mapBack, CONVERTERS_NAMES[i].name);
   1344         }
   1345     }
   1346 
   1347 }
   1348 
   1349 static void TestDuplicateAlias(void) {
   1350     const char *alias;
   1351     UErrorCode status = U_ZERO_ERROR;
   1352 
   1353     status = U_ZERO_ERROR;
   1354     alias = ucnv_getStandardName("Shift_JIS", "IBM", &status);
   1355     if (alias == NULL || strcmp(alias, "ibm-943") != 0 || status != U_AMBIGUOUS_ALIAS_WARNING) {
   1356         log_data_err("FAIL: Didn't get ibm-943 for Shift_JIS {IBM}. Got %s\n", alias);
   1357     }
   1358     status = U_ZERO_ERROR;
   1359     alias = ucnv_getStandardName("ibm-943", "IANA", &status);
   1360     if (alias == NULL || strcmp(alias, "Shift_JIS") != 0 || status != U_AMBIGUOUS_ALIAS_WARNING) {
   1361         log_data_err("FAIL: Didn't get Shift_JIS for ibm-943 {IANA}. Got %s\n", alias);
   1362     }
   1363     status = U_ZERO_ERROR;
   1364     alias = ucnv_getStandardName("ibm-943_P130-2000", "IANA", &status);
   1365     if (alias != NULL || status == U_AMBIGUOUS_ALIAS_WARNING) {
   1366         log_data_err("FAIL: Didn't get NULL for ibm-943 {IANA}. Got %s\n", alias);
   1367     }
   1368 }
   1369 
   1370 
   1371 /* Test safe clone callback */
   1372 
   1373 static uint32_t    TSCC_nextSerial()
   1374 {
   1375     static uint32_t n = 1;
   1376 
   1377     return (n++);
   1378 }
   1379 
   1380 typedef struct
   1381 {
   1382     uint32_t       magic;      /* 0xC0FFEE to identify that the object is OK */
   1383     uint32_t       serial;     /* minted from nextSerial, above */
   1384     UBool          wasClosed;  /* close happened on the object */
   1385 } TSCCContext;
   1386 
   1387 static TSCCContext *TSCC_clone(TSCCContext *ctx)
   1388 {
   1389     TSCCContext *newCtx = (TSCCContext *)malloc(sizeof(TSCCContext));
   1390 
   1391     newCtx->serial = TSCC_nextSerial();
   1392     newCtx->wasClosed = 0;
   1393     newCtx->magic = 0xC0FFEE;
   1394 
   1395     log_verbose("TSCC_clone: %p:%d -> new context %p:%d\n", ctx, ctx->serial, newCtx, newCtx->serial);
   1396 
   1397     return newCtx;
   1398 }
   1399 
   1400 static void TSCC_fromU(const void *context,
   1401                         UConverterFromUnicodeArgs *fromUArgs,
   1402                         const UChar* codeUnits,
   1403                         int32_t length,
   1404                         UChar32 codePoint,
   1405                         UConverterCallbackReason reason,
   1406                         UErrorCode * err)
   1407 {
   1408     TSCCContext *ctx = (TSCCContext*)context;
   1409     UConverterFromUCallback junkFrom;
   1410 
   1411     log_verbose("TSCC_fromU: Context %p:%d called, reason %d on cnv %p\n", ctx, ctx->serial, reason, fromUArgs->converter);
   1412 
   1413     if(ctx->magic != 0xC0FFEE) {
   1414         log_err("TSCC_fromU: Context %p:%d magic is 0x%x should be 0xC0FFEE.\n", ctx,ctx->serial, ctx->magic);
   1415         return;
   1416     }
   1417 
   1418     if(reason == UCNV_CLONE) {
   1419         UErrorCode subErr = U_ZERO_ERROR;
   1420         TSCCContext *newCtx;
   1421         TSCCContext *junkCtx;
   1422         TSCCContext **pjunkCtx = &junkCtx;
   1423 
   1424         /* "recreate" it */
   1425         log_verbose("TSCC_fromU: cloning..\n");
   1426         newCtx = TSCC_clone(ctx);
   1427 
   1428         if(newCtx == NULL) {
   1429             log_err("TSCC_fromU: internal clone failed on %p\n", ctx);
   1430         }
   1431 
   1432         /* now, SET it */
   1433         ucnv_getFromUCallBack(fromUArgs->converter, &junkFrom, (const void**)pjunkCtx);
   1434         ucnv_setFromUCallBack(fromUArgs->converter, junkFrom, newCtx, NULL, NULL, &subErr);
   1435 
   1436         if(U_FAILURE(subErr)) {
   1437             *err = subErr;
   1438         }
   1439     }
   1440 
   1441     if(reason == UCNV_CLOSE) {
   1442         log_verbose("TSCC_fromU: Context %p:%d closing\n", ctx, ctx->serial);
   1443         ctx->wasClosed = TRUE;
   1444     }
   1445 }
   1446 
   1447 
   1448 static void TSCC_toU(const void *context,
   1449                         UConverterToUnicodeArgs *toUArgs,
   1450                         const char* codeUnits,
   1451                         int32_t length,
   1452                         UConverterCallbackReason reason,
   1453                         UErrorCode * err)
   1454 {
   1455     TSCCContext *ctx = (TSCCContext*)context;
   1456     UConverterToUCallback junkFrom;
   1457 
   1458     log_verbose("TSCC_toU: Context %p:%d called, reason %d on cnv %p\n", ctx, ctx->serial, reason, toUArgs->converter);
   1459 
   1460     if(ctx->magic != 0xC0FFEE) {
   1461         log_err("TSCC_toU: Context %p:%d magic is 0x%x should be 0xC0FFEE.\n", ctx,ctx->serial, ctx->magic);
   1462         return;
   1463     }
   1464 
   1465     if(reason == UCNV_CLONE) {
   1466         UErrorCode subErr = U_ZERO_ERROR;
   1467         TSCCContext *newCtx;
   1468         TSCCContext *junkCtx;
   1469         TSCCContext **pjunkCtx = &junkCtx;
   1470 
   1471         /* "recreate" it */
   1472         log_verbose("TSCC_toU: cloning..\n");
   1473         newCtx = TSCC_clone(ctx);
   1474 
   1475         if(newCtx == NULL) {
   1476             log_err("TSCC_toU: internal clone failed on %p\n", ctx);
   1477         }
   1478 
   1479         /* now, SET it */
   1480         ucnv_getToUCallBack(toUArgs->converter, &junkFrom, (const void**)pjunkCtx);
   1481         ucnv_setToUCallBack(toUArgs->converter, junkFrom, newCtx, NULL, NULL, &subErr);
   1482 
   1483         if(U_FAILURE(subErr)) {
   1484             *err = subErr;
   1485         }
   1486     }
   1487 
   1488     if(reason == UCNV_CLOSE) {
   1489         log_verbose("TSCC_toU: Context %p:%d closing\n", ctx, ctx->serial);
   1490         ctx->wasClosed = TRUE;
   1491     }
   1492 }
   1493 
   1494 static void TSCC_init(TSCCContext *q)
   1495 {
   1496     q->magic = 0xC0FFEE;
   1497     q->serial = TSCC_nextSerial();
   1498     q->wasClosed = 0;
   1499 }
   1500 
   1501 static void TSCC_print_log(TSCCContext *q, const char *name)
   1502 {
   1503     if(q==NULL) {
   1504         log_verbose("TSCContext: %s is NULL!!\n", name);
   1505     } else {
   1506         if(q->magic != 0xC0FFEE) {
   1507             log_err("TSCCContext: %p:%d's magic is %x, supposed to be 0xC0FFEE\n",
   1508                     q,q->serial, q->magic);
   1509         }
   1510         log_verbose("TSCCContext %p:%d=%s - magic %x, %s\n",
   1511                     q, q->serial, name, q->magic, q->wasClosed?"CLOSED":"open");
   1512     }
   1513 }
   1514 
   1515 #if !UCONFIG_NO_LEGACY_CONVERSION
   1516 static void TestConvertSafeCloneCallback()
   1517 {
   1518     UErrorCode err = U_ZERO_ERROR;
   1519     TSCCContext from1, to1;
   1520     TSCCContext *from2, *from3, *to2, *to3;
   1521     TSCCContext **pfrom2 = &from2, **pfrom3 = &from3, **pto2 = &to2, **pto3 = &to3;
   1522     char hunk[8192];
   1523     int32_t hunkSize = 8192;
   1524     UConverterFromUCallback junkFrom;
   1525     UConverterToUCallback junkTo;
   1526     UConverter *conv1, *conv2 = NULL;
   1527 
   1528     conv1 = ucnv_open("iso-8859-3", &err);
   1529 
   1530     if(U_FAILURE(err)) {
   1531         log_data_err("Err opening iso-8859-3, %s\n", u_errorName(err));
   1532         return;
   1533     }
   1534 
   1535     log_verbose("Opened conv1=%p\n", conv1);
   1536 
   1537     TSCC_init(&from1);
   1538     TSCC_init(&to1);
   1539 
   1540     TSCC_print_log(&from1, "from1");
   1541     TSCC_print_log(&to1, "to1");
   1542 
   1543     ucnv_setFromUCallBack(conv1, TSCC_fromU, &from1, NULL, NULL, &err);
   1544     log_verbose("Set from1 on conv1\n");
   1545     TSCC_print_log(&from1, "from1");
   1546 
   1547     ucnv_setToUCallBack(conv1, TSCC_toU, &to1, NULL, NULL, &err);
   1548     log_verbose("Set to1 on conv1\n");
   1549     TSCC_print_log(&to1, "to1");
   1550 
   1551     conv2 = ucnv_safeClone(conv1, hunk, &hunkSize, &err);
   1552     if(U_FAILURE(err)) {
   1553         log_err("safeClone failed: %s\n", u_errorName(err));
   1554         return;
   1555     }
   1556     log_verbose("Cloned to conv2=%p.\n", conv2);
   1557 
   1558 /**********   from *********************/
   1559     ucnv_getFromUCallBack(conv2, &junkFrom, (const void**)pfrom2);
   1560     ucnv_getFromUCallBack(conv1, &junkFrom, (const void**)pfrom3);
   1561 
   1562     TSCC_print_log(from2, "from2");
   1563     TSCC_print_log(from3, "from3(==from1)");
   1564 
   1565     if(from2 == NULL) {
   1566         log_err("FAIL! from2 is null \n");
   1567         return;
   1568     }
   1569 
   1570     if(from3 == NULL) {
   1571         log_err("FAIL! from3 is null \n");
   1572         return;
   1573     }
   1574 
   1575     if(from3 != (&from1) ) {
   1576         log_err("FAIL! conv1's FROM context changed!\n");
   1577     }
   1578 
   1579     if(from2 == (&from1) ) {
   1580         log_err("FAIL! conv1's FROM context is the same as conv2's!\n");
   1581     }
   1582 
   1583     if(from1.wasClosed) {
   1584         log_err("FAIL! from1 is closed \n");
   1585     }
   1586 
   1587     if(from2->wasClosed) {
   1588         log_err("FAIL! from2 was closed\n");
   1589     }
   1590 
   1591 /**********   to *********************/
   1592     ucnv_getToUCallBack(conv2, &junkTo, (const void**)pto2);
   1593     ucnv_getToUCallBack(conv1, &junkTo, (const void**)pto3);
   1594 
   1595     TSCC_print_log(to2, "to2");
   1596     TSCC_print_log(to3, "to3(==to1)");
   1597 
   1598     if(to2 == NULL) {
   1599         log_err("FAIL! to2 is null \n");
   1600         return;
   1601     }
   1602 
   1603     if(to3 == NULL) {
   1604         log_err("FAIL! to3 is null \n");
   1605         return;
   1606     }
   1607 
   1608     if(to3 != (&to1) ) {
   1609         log_err("FAIL! conv1's TO context changed!\n");
   1610     }
   1611 
   1612     if(to2 == (&to1) ) {
   1613         log_err("FAIL! conv1's TO context is the same as conv2's!\n");
   1614     }
   1615 
   1616     if(to1.wasClosed) {
   1617         log_err("FAIL! to1 is closed \n");
   1618     }
   1619 
   1620     if(to2->wasClosed) {
   1621         log_err("FAIL! to2 was closed\n");
   1622     }
   1623 
   1624 /*************************************/
   1625 
   1626     ucnv_close(conv1);
   1627     log_verbose("ucnv_closed (conv1)\n");
   1628     TSCC_print_log(&from1, "from1");
   1629     TSCC_print_log(from2, "from2");
   1630     TSCC_print_log(&to1, "to1");
   1631     TSCC_print_log(to2, "to2");
   1632 
   1633     if(from1.wasClosed == FALSE) {
   1634         log_err("FAIL! from1 is NOT closed \n");
   1635     }
   1636 
   1637     if(from2->wasClosed) {
   1638         log_err("FAIL! from2 was closed\n");
   1639     }
   1640 
   1641     if(to1.wasClosed == FALSE) {
   1642         log_err("FAIL! to1 is NOT closed \n");
   1643     }
   1644 
   1645     if(to2->wasClosed) {
   1646         log_err("FAIL! to2 was closed\n");
   1647     }
   1648 
   1649     ucnv_close(conv2);
   1650     log_verbose("ucnv_closed (conv2)\n");
   1651 
   1652     TSCC_print_log(&from1, "from1");
   1653     TSCC_print_log(from2, "from2");
   1654 
   1655     if(from1.wasClosed == FALSE) {
   1656         log_err("FAIL! from1 is NOT closed \n");
   1657     }
   1658 
   1659     if(from2->wasClosed == FALSE) {
   1660         log_err("FAIL! from2 was NOT closed\n");
   1661     }
   1662 
   1663     TSCC_print_log(&to1, "to1");
   1664     TSCC_print_log(to2, "to2");
   1665 
   1666     if(to1.wasClosed == FALSE) {
   1667         log_err("FAIL! to1 is NOT closed \n");
   1668     }
   1669 
   1670     if(to2->wasClosed == FALSE) {
   1671         log_err("FAIL! to2 was NOT closed\n");
   1672     }
   1673 
   1674     if(to2 != (&to1)) {
   1675         free(to2); /* to1 is stack based */
   1676     }
   1677     if(from2 != (&from1)) {
   1678         free(from2); /* from1 is stack based */
   1679     }
   1680 }
   1681 #endif
   1682 
   1683 static UBool
   1684 containsAnyOtherByte(uint8_t *p, int32_t length, uint8_t b) {
   1685     while(length>0) {
   1686         if(*p!=b) {
   1687             return TRUE;
   1688         }
   1689         ++p;
   1690         --length;
   1691     }
   1692     return FALSE;
   1693 }
   1694 
   1695 static void TestConvertSafeClone()
   1696 {
   1697     /* one 'regular' & all the 'private stateful' converters */
   1698     static const char *const names[] = {
   1699 #if !UCONFIG_NO_LEGACY_CONVERSION
   1700         "ibm-1047",
   1701         "ISO_2022,locale=zh,version=1",
   1702 #endif
   1703         "SCSU",
   1704 #if !UCONFIG_NO_LEGACY_CONVERSION
   1705         "HZ",
   1706         "lmbcs",
   1707         "ISCII,version=0",
   1708         "ISO_2022,locale=kr,version=1",
   1709         "ISO_2022,locale=jp,version=2",
   1710 #endif
   1711         "BOCU-1",
   1712         "UTF-7",
   1713 #if !UCONFIG_NO_LEGACY_CONVERSION
   1714         "IMAP-mailbox-name",
   1715         "ibm-1047-s390"
   1716 #else
   1717         "IMAP=mailbox-name"
   1718 #endif
   1719     };
   1720 
   1721     /* store the actual sizes of each converter */
   1722     int32_t actualSizes[LENGTHOF(names)];
   1723 
   1724     static const int32_t bufferSizes[] = {
   1725         U_CNV_SAFECLONE_BUFFERSIZE,
   1726         (int32_t)(3*sizeof(UConverter))/2,  /* 1.5*sizeof(UConverter) */
   1727         (int32_t)sizeof(UConverter)/2       /* 0.5*sizeof(UConverter) */
   1728     };
   1729 
   1730     char charBuffer[21];   /* Leave at an odd number for alignment testing */
   1731     uint8_t buffer[3] [U_CNV_SAFECLONE_BUFFERSIZE];
   1732     int32_t bufferSize, maxBufferSize;
   1733     const char *maxName;
   1734     UConverter * cnv, *cnv2;
   1735     UErrorCode err;
   1736 
   1737     char *pCharBuffer;
   1738     const char *pConstCharBuffer;
   1739     const char *charBufferLimit = charBuffer + sizeof(charBuffer)/sizeof(*charBuffer);
   1740     UChar uniBuffer[] = {0x0058, 0x0059, 0x005A}; /* "XYZ" */
   1741     UChar uniCharBuffer[20];
   1742     char  charSourceBuffer[] = { 0x1b, 0x24, 0x42 };
   1743     const char *pCharSource = charSourceBuffer;
   1744     const char *pCharSourceLimit = charSourceBuffer + sizeof(charSourceBuffer);
   1745     UChar *pUCharTarget = uniCharBuffer;
   1746     UChar *pUCharTargetLimit = uniCharBuffer + sizeof(uniCharBuffer)/sizeof(*uniCharBuffer);
   1747     const UChar * pUniBuffer;
   1748     const UChar *uniBufferLimit = uniBuffer + sizeof(uniBuffer)/sizeof(*uniBuffer);
   1749     int32_t index, j;
   1750 
   1751     err = U_ZERO_ERROR;
   1752     cnv = ucnv_open(names[0], &err);
   1753     if(U_SUCCESS(err)) {
   1754         /* Check the various error & informational states: */
   1755 
   1756         /* Null status - just returns NULL */
   1757         bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
   1758         if (0 != ucnv_safeClone(cnv, buffer[0], &bufferSize, 0))
   1759         {
   1760             log_err("FAIL: Cloned converter failed to deal correctly with null status\n");
   1761         }
   1762         /* error status - should return 0 & keep error the same */
   1763         err = U_MEMORY_ALLOCATION_ERROR;
   1764         if (0 != ucnv_safeClone(cnv, buffer[0], &bufferSize, &err) || err != U_MEMORY_ALLOCATION_ERROR)
   1765         {
   1766             log_err("FAIL: Cloned converter failed to deal correctly with incoming error status\n");
   1767         }
   1768         err = U_ZERO_ERROR;
   1769 
   1770         /* Null buffer size pointer - just returns NULL & set error to U_ILLEGAL_ARGUMENT_ERROR*/
   1771         if (0 != ucnv_safeClone(cnv, buffer[0], 0, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
   1772         {
   1773             log_err("FAIL: Cloned converter failed to deal correctly with null bufferSize pointer\n");
   1774         }
   1775         err = U_ZERO_ERROR;
   1776 
   1777         /* buffer size pointer is 0 - fill in pbufferSize with a size */
   1778         bufferSize = 0;
   1779         if (0 != ucnv_safeClone(cnv, buffer[0], &bufferSize, &err) || U_FAILURE(err) || bufferSize <= 0)
   1780         {
   1781             log_err("FAIL: Cloned converter failed a sizing request ('preflighting')\n");
   1782         }
   1783         /* Verify our define is large enough  */
   1784         if (U_CNV_SAFECLONE_BUFFERSIZE < bufferSize)
   1785         {
   1786             log_err("FAIL: Pre-calculated buffer size is too small\n");
   1787         }
   1788         /* Verify we can use this run-time calculated size */
   1789         if (0 == (cnv2 = ucnv_safeClone(cnv, buffer[0], &bufferSize, &err)) || U_FAILURE(err))
   1790         {
   1791             log_err("FAIL: Converter can't be cloned with run-time size\n");
   1792         }
   1793         if (cnv2) {
   1794             ucnv_close(cnv2);
   1795         }
   1796 
   1797         /* size one byte too small - should allocate & let us know */
   1798         --bufferSize;
   1799         if (0 == (cnv2 = ucnv_safeClone(cnv, 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
   1800         {
   1801             log_err("FAIL: Cloned converter failed to deal correctly with too-small buffer size\n");
   1802         }
   1803         if (cnv2) {
   1804             ucnv_close(cnv2);
   1805         }
   1806 
   1807         err = U_ZERO_ERROR;
   1808         bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
   1809 
   1810         /* Null buffer pointer - return converter & set error to U_SAFECLONE_ALLOCATED_ERROR */
   1811         if (0 == (cnv2 = ucnv_safeClone(cnv, 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
   1812         {
   1813             log_err("FAIL: Cloned converter failed to deal correctly with null buffer pointer\n");
   1814         }
   1815         if (cnv2) {
   1816             ucnv_close(cnv2);
   1817         }
   1818 
   1819         err = U_ZERO_ERROR;
   1820 
   1821         /* Null converter - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
   1822         if (0 != ucnv_safeClone(0, buffer[0], &bufferSize, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
   1823         {
   1824             log_err("FAIL: Cloned converter failed to deal correctly with null converter pointer\n");
   1825         }
   1826 
   1827         ucnv_close(cnv);
   1828     }
   1829 
   1830     maxBufferSize = 0;
   1831     maxName = "";
   1832 
   1833     /* Do these cloned converters work at all - shuffle UChars to chars & back again..*/
   1834 
   1835     for(j = 0; j < LENGTHOF(bufferSizes); ++j) {
   1836         for (index = 0; index < LENGTHOF(names); index++)
   1837         {
   1838             err = U_ZERO_ERROR;
   1839             cnv = ucnv_open(names[index], &err);
   1840             if(U_FAILURE(err)) {
   1841                 log_data_err("ucnv_open(\"%s\") failed - %s\n", names[index], u_errorName(err));
   1842                 continue;
   1843             }
   1844 
   1845             if(j == 0) {
   1846                 /* preflight to get maxBufferSize */
   1847                 actualSizes[index] = 0;
   1848                 ucnv_safeClone(cnv, NULL, &actualSizes[index], &err);
   1849                 if(actualSizes[index] > maxBufferSize) {
   1850                     maxBufferSize = actualSizes[index];
   1851                     maxName = names[index];
   1852                 }
   1853             }
   1854 
   1855             memset(buffer, 0xaa, sizeof(buffer));
   1856 
   1857             bufferSize = bufferSizes[j];
   1858             cnv2 = ucnv_safeClone(cnv, buffer[1], &bufferSize, &err);
   1859 
   1860             /* close the original immediately to make sure that the clone works by itself */
   1861             ucnv_close(cnv);
   1862 
   1863             if( actualSizes[index] <= (bufferSizes[j] - (int32_t)sizeof(UAlignedMemory)) &&
   1864                 err == U_SAFECLONE_ALLOCATED_WARNING
   1865             ) {
   1866                 log_err("ucnv_safeClone(%s) did a heap clone although the buffer was large enough\n", names[index]);
   1867             }
   1868 
   1869             /* check if the clone function overwrote any bytes that it is not supposed to touch */
   1870             if(bufferSize <= bufferSizes[j]) {
   1871                 /* used the stack buffer */
   1872                 if( containsAnyOtherByte(buffer[0], (int32_t)sizeof(buffer[0]), 0xaa) ||
   1873                     containsAnyOtherByte(buffer[1]+bufferSize, (int32_t)(sizeof(buffer)-(sizeof(buffer[0])+bufferSize)), 0xaa)
   1874                 ) {
   1875                     log_err("cloning %s in a stack buffer overwrote bytes outside the bufferSize %d (requested %d)\n",
   1876                         names[index], bufferSize, bufferSizes[j]);
   1877                 }
   1878             } else {
   1879                 /* heap-allocated the clone */
   1880                 if(containsAnyOtherByte(buffer[0], (int32_t)sizeof(buffer), 0xaa)) {
   1881                     log_err("cloning %s used the heap (bufferSize %d, requested %d) but overwrote stack buffer bytes\n",
   1882                         names[index], bufferSize, bufferSizes[j]);
   1883                 }
   1884             }
   1885 
   1886             pCharBuffer = charBuffer;
   1887             pUniBuffer = uniBuffer;
   1888 
   1889             ucnv_fromUnicode(cnv2,
   1890                             &pCharBuffer,
   1891                             charBufferLimit,
   1892                             &pUniBuffer,
   1893                             uniBufferLimit,
   1894                             NULL,
   1895                             TRUE,
   1896                             &err);
   1897             if(U_FAILURE(err)){
   1898                 log_err("FAIL: cloned converter failed to do fromU conversion. Error: %s\n",u_errorName(err));
   1899             }
   1900             ucnv_toUnicode(cnv2,
   1901                            &pUCharTarget,
   1902                            pUCharTargetLimit,
   1903                            &pCharSource,
   1904                            pCharSourceLimit,
   1905                            NULL,
   1906                            TRUE,
   1907                            &err
   1908                            );
   1909 
   1910             if(U_FAILURE(err)){
   1911                 log_err("FAIL: cloned converter failed to do toU conversion. Error: %s\n",u_errorName(err));
   1912             }
   1913 
   1914             pConstCharBuffer = charBuffer;
   1915             if (uniBuffer [0] != ucnv_getNextUChar(cnv2, &pConstCharBuffer, pCharBuffer, &err))
   1916             {
   1917                 log_err("FAIL: Cloned converter failed to do conversion. Error: %s\n",u_errorName(err));
   1918             }
   1919             ucnv_close(cnv2);
   1920         }
   1921     }
   1922 
   1923     log_verbose("ucnv_safeClone(): sizeof(UConverter)=%lu  max preflighted clone size=%d (%s)  U_CNV_SAFECLONE_BUFFERSIZE=%d\n",
   1924         sizeof(UConverter), maxBufferSize, maxName, (int)U_CNV_SAFECLONE_BUFFERSIZE);
   1925     if(maxBufferSize > U_CNV_SAFECLONE_BUFFERSIZE) {
   1926         log_err("ucnv_safeClone(): max preflighted clone size=%d (%s) is larger than U_CNV_SAFECLONE_BUFFERSIZE=%d\n",
   1927             maxBufferSize, maxName, (int)U_CNV_SAFECLONE_BUFFERSIZE);
   1928     }
   1929 }
   1930 
   1931 static void TestCCSID() {
   1932 #if !UCONFIG_NO_LEGACY_CONVERSION
   1933     UConverter *cnv;
   1934     UErrorCode errorCode;
   1935     int32_t ccsids[]={ 37, 850, 943, 949, 950, 1047, 1252, 1392, 33722 };
   1936     int32_t i, ccsid;
   1937 
   1938     for(i=0; i<(int32_t)(sizeof(ccsids)/sizeof(int32_t)); ++i) {
   1939         ccsid=ccsids[i];
   1940 
   1941         errorCode=U_ZERO_ERROR;
   1942         cnv=ucnv_openCCSID(ccsid, UCNV_IBM, &errorCode);
   1943         if(U_FAILURE(errorCode)) {
   1944         log_data_err("error: ucnv_openCCSID(%ld) failed (%s)\n", ccsid, u_errorName(errorCode));
   1945             continue;
   1946         }
   1947 
   1948         if(ccsid!=ucnv_getCCSID(cnv, &errorCode)) {
   1949             log_err("error: ucnv_getCCSID(ucnv_openCCSID(%ld))=%ld\n", ccsid, ucnv_getCCSID(cnv, &errorCode));
   1950         }
   1951 
   1952         /* skip gb18030(ccsid 1392) */
   1953         if(ccsid != 1392 && UCNV_IBM!=ucnv_getPlatform(cnv, &errorCode)) {
   1954             log_err("error: ucnv_getPlatform(ucnv_openCCSID(%ld))=%ld!=UCNV_IBM\n", ccsid, ucnv_getPlatform(cnv, &errorCode));
   1955         }
   1956 
   1957         ucnv_close(cnv);
   1958     }
   1959 #endif
   1960 }
   1961 
   1962 /* jitterbug 932: ucnv_convert() bugs --------------------------------------- */
   1963 
   1964 /* CHUNK_SIZE defined in common\ucnv.c: */
   1965 #define CHUNK_SIZE 1024
   1966 
   1967 static void bug1(void);
   1968 static void bug2(void);
   1969 static void bug3(void);
   1970 
   1971 static void
   1972 TestJ932(void)
   1973 {
   1974    bug1(); /* Unicode intermediate buffer straddle bug */
   1975    bug2(); /* pre-flighting size incorrect caused by simple overflow */
   1976    bug3(); /* pre-flighting size incorrect caused by expansion overflow */
   1977 }
   1978 
   1979 /*
   1980  * jitterbug 932: test chunking boundary conditions in
   1981 
   1982     int32_t  ucnv_convert(const char *toConverterName,
   1983                           const char *fromConverterName,
   1984                           char *target,
   1985                           int32_t targetSize,
   1986                           const char *source,
   1987                           int32_t sourceSize,
   1988                           UErrorCode * err)
   1989 
   1990  * See discussions on the icu mailing list in
   1991  * 2001-April with the subject "converter 'flush' question".
   1992  *
   1993  * Bug report and test code provided by Edward J. Batutis.
   1994  */
   1995 static void bug1()
   1996 {
   1997 #if !UCONFIG_NO_LEGACY_CONVERSION
   1998    char char_in[CHUNK_SIZE+32];
   1999    char char_out[CHUNK_SIZE*2];
   2000 
   2001    /* GB 18030 equivalent of U+10000 is 90308130 */
   2002    static const char test_seq[]={ (char)0x90u, 0x30, (char)0x81u, 0x30 };
   2003 
   2004    UErrorCode err = U_ZERO_ERROR;
   2005    int32_t i, test_seq_len = sizeof(test_seq);
   2006 
   2007    /*
   2008     * causes straddle bug in Unicode intermediate buffer by sliding the test sequence forward
   2009     * until the straddle bug appears. I didn't want to hard-code everything so this test could
   2010     * be expanded - however this is the only type of straddle bug I can think of at the moment -
   2011     * a high surrogate in the last position of the Unicode intermediate buffer. Apparently no
   2012     * other Unicode sequences cause a bug since combining sequences are not supported by the
   2013     * converters.
   2014     */
   2015 
   2016    for (i = test_seq_len; i >= 0; i--) {
   2017       /* put character sequence into input buffer */
   2018       memset(char_in, 0x61, sizeof(char_in)); /* GB 18030 'a' */
   2019       memcpy(char_in + (CHUNK_SIZE - i), test_seq, test_seq_len);
   2020 
   2021       /* do the conversion */
   2022       ucnv_convert("us-ascii", /* out */
   2023                    "gb18030",  /* in */
   2024                    char_out,
   2025                    sizeof(char_out),
   2026                    char_in,
   2027                    sizeof(char_in),
   2028                    &err);
   2029 
   2030       /* bug1: */
   2031       if (err == U_TRUNCATED_CHAR_FOUND) {
   2032          /* this happens when surrogate pair straddles the intermediate buffer in
   2033           * T_UConverter_fromCodepageToCodepage */
   2034          log_err("error j932 bug 1: expected success, got U_TRUNCATED_CHAR_FOUND\n");
   2035       }
   2036    }
   2037 #endif
   2038 }
   2039 
   2040 /* bug2: pre-flighting loop bug: simple overflow causes bug */
   2041 static void bug2()
   2042 {
   2043     /* US-ASCII "1234567890" */
   2044     static const char source[]={ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 };
   2045     static const char sourceUTF8[]={ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, (char)0xef, (char)0x80, (char)0x80 };
   2046     static const char sourceUTF32[]={ 0x00, 0x00, 0x00, 0x30,
   2047                                       0x00, 0x00, 0x00, 0x31,
   2048                                       0x00, 0x00, 0x00, 0x32,
   2049                                       0x00, 0x00, 0x00, 0x33,
   2050                                       0x00, 0x00, 0x00, 0x34,
   2051                                       0x00, 0x00, 0x00, 0x35,
   2052                                       0x00, 0x00, 0x00, 0x36,
   2053                                       0x00, 0x00, 0x00, 0x37,
   2054                                       0x00, 0x00, 0x00, 0x38,
   2055                                       0x00, 0x00, (char)0xf0, 0x00};
   2056     static char target[5];
   2057 
   2058     UErrorCode err = U_ZERO_ERROR;
   2059     int32_t size;
   2060 
   2061     /* do the conversion */
   2062     size = ucnv_convert("iso-8859-1", /* out */
   2063                         "us-ascii",  /* in */
   2064                         target,
   2065                         sizeof(target),
   2066                         source,
   2067                         sizeof(source),
   2068                         &err);
   2069 
   2070     if ( size != 10 ) {
   2071         /* bug2: size is 5, should be 10 */
   2072         log_data_err("error j932 bug 2 us-ascii->iso-8859-1: got preflighting size %d instead of 10\n", size);
   2073     }
   2074 
   2075     err = U_ZERO_ERROR;
   2076     /* do the conversion */
   2077     size = ucnv_convert("UTF-32BE", /* out */
   2078                         "UTF-8",  /* in */
   2079                         target,
   2080                         sizeof(target),
   2081                         sourceUTF8,
   2082                         sizeof(sourceUTF8),
   2083                         &err);
   2084 
   2085     if ( size != 32 ) {
   2086         /* bug2: size is 5, should be 32 */
   2087         log_err("error j932 bug 2 UTF-8->UTF-32BE: got preflighting size %d instead of 32\n", size);
   2088     }
   2089 
   2090     err = U_ZERO_ERROR;
   2091     /* do the conversion */
   2092     size = ucnv_convert("UTF-8", /* out */
   2093                         "UTF-32BE",  /* in */
   2094                         target,
   2095                         sizeof(target),
   2096                         sourceUTF32,
   2097                         sizeof(sourceUTF32),
   2098                         &err);
   2099 
   2100     if ( size != 12 ) {
   2101         /* bug2: size is 5, should be 12 */
   2102         log_err("error j932 bug 2 UTF-32BE->UTF-8: got preflighting size %d instead of 12\n", size);
   2103     }
   2104 }
   2105 
   2106 /*
   2107  * bug3: when the characters expand going from source to target codepage
   2108  *       you get bug3 in addition to bug2
   2109  */
   2110 static void bug3()
   2111 {
   2112 #if !UCONFIG_NO_LEGACY_CONVERSION
   2113     char char_in[CHUNK_SIZE*4];
   2114     char target[5];
   2115     UErrorCode err = U_ZERO_ERROR;
   2116     int32_t size;
   2117 
   2118     /*
   2119      * first get the buggy size from bug2 then
   2120      * compare it to buggy size with an expansion
   2121      */
   2122     memset(char_in, 0x61, sizeof(char_in)); /* US-ASCII 'a' */
   2123 
   2124     /* do the conversion */
   2125     size = ucnv_convert("lmbcs",     /* out */
   2126                         "us-ascii",  /* in */
   2127                         target,
   2128                         sizeof(target),
   2129                         char_in,
   2130                         sizeof(char_in),
   2131                         &err);
   2132 
   2133     if ( size != sizeof(char_in) ) {
   2134         /*
   2135          * bug2: size is 0x2805 (CHUNK_SIZE*2+5 - maybe 5 is the size of the overflow buffer
   2136          * in the converter?), should be CHUNK_SIZE*4
   2137          *
   2138          * Markus 2001-05-18: 5 is the size of our target[] here, ucnv_convert() did not reset targetSize...
   2139          */
   2140         log_data_err("error j932 bug 2/3a: expected preflighting size 0x%04x, got 0x%04x\n", sizeof(char_in), size);
   2141     }
   2142 
   2143     /*
   2144      * now do the conversion with expansion
   2145      * ascii 0x08 expands to 0x0F 0x28 in lmbcs
   2146      */
   2147     memset(char_in, 8, sizeof(char_in));
   2148     err = U_ZERO_ERROR;
   2149 
   2150     /* do the conversion */
   2151     size = ucnv_convert("lmbcs", /* out */
   2152                         "us-ascii",  /* in */
   2153                         target,
   2154                         sizeof(target),
   2155                         char_in,
   2156                         sizeof(char_in),
   2157                         &err);
   2158 
   2159     /* expect 2X expansion */
   2160     if ( size != sizeof(char_in) * 2 ) {
   2161         /*
   2162          * bug3:
   2163          * bug2 would lead us to expect 0x2805, but it isn't that either, it is 0x3c05:
   2164          */
   2165         log_data_err("error j932 bug 3b: expected 0x%04x, got 0x%04x\n", sizeof(char_in) * 2, size);
   2166     }
   2167 #endif
   2168 }
   2169 
   2170 static void
   2171 convertExStreaming(UConverter *srcCnv, UConverter *targetCnv,
   2172                    const char *src, int32_t srcLength,
   2173                    const char *expectTarget, int32_t expectTargetLength,
   2174                    int32_t chunkSize,
   2175                    const char *testName,
   2176                    UErrorCode expectCode) {
   2177     UChar pivotBuffer[CHUNK_SIZE];
   2178     UChar *pivotSource, *pivotTarget;
   2179     const UChar *pivotLimit;
   2180 
   2181     char targetBuffer[CHUNK_SIZE];
   2182     char *target;
   2183     const char *srcLimit, *finalSrcLimit, *targetLimit;
   2184 
   2185     int32_t targetLength;
   2186 
   2187     UBool flush;
   2188 
   2189     UErrorCode errorCode;
   2190 
   2191     /* setup */
   2192     if(chunkSize>CHUNK_SIZE) {
   2193         chunkSize=CHUNK_SIZE;
   2194     }
   2195 
   2196     pivotSource=pivotTarget=pivotBuffer;
   2197     pivotLimit=pivotBuffer+chunkSize;
   2198 
   2199     finalSrcLimit=src+srcLength;
   2200     target=targetBuffer;
   2201     targetLimit=targetBuffer+chunkSize;
   2202 
   2203     ucnv_resetToUnicode(srcCnv);
   2204     ucnv_resetFromUnicode(targetCnv);
   2205 
   2206     errorCode=U_ZERO_ERROR;
   2207     flush=FALSE;
   2208 
   2209     /* convert, streaming-style (both converters and pivot keep state) */
   2210     for(;;) {
   2211         /* for testing, give ucnv_convertEx() at most <chunkSize> input/pivot/output units at a time */
   2212         if(src+chunkSize<=finalSrcLimit) {
   2213             srcLimit=src+chunkSize;
   2214         } else {
   2215             srcLimit=finalSrcLimit;
   2216         }
   2217         ucnv_convertEx(targetCnv, srcCnv,
   2218                        &target, targetLimit,
   2219                        &src, srcLimit,
   2220                        pivotBuffer, &pivotSource, &pivotTarget, pivotLimit,
   2221                        FALSE, flush, &errorCode);
   2222         targetLength=(int32_t)(target-targetBuffer);
   2223         if(target>targetLimit) {
   2224             log_err("ucnv_convertEx(%s) chunk[%d] target %p exceeds targetLimit %p\n",
   2225                     testName, chunkSize, target, targetLimit);
   2226             break; /* TODO: major problem! */
   2227         }
   2228         if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
   2229             /* continue converting another chunk */
   2230             errorCode=U_ZERO_ERROR;
   2231             if(targetLength+chunkSize<=sizeof(targetBuffer)) {
   2232                 targetLimit=target+chunkSize;
   2233             } else {
   2234                 targetLimit=targetBuffer+sizeof(targetBuffer);
   2235             }
   2236         } else if(U_FAILURE(errorCode)) {
   2237             /* failure */
   2238             break;
   2239         } else if(flush) {
   2240             /* all done */
   2241             break;
   2242         } else if(src==finalSrcLimit && pivotSource==pivotTarget) {
   2243             /* all consumed, now flush without input (separate from conversion for testing) */
   2244             flush=TRUE;
   2245         }
   2246     }
   2247 
   2248     if(!(errorCode==expectCode || (expectCode==U_ZERO_ERROR && errorCode==U_STRING_NOT_TERMINATED_WARNING))) {
   2249         log_err("ucnv_convertEx(%s) chunk[%d] results in %s instead of %s\n",
   2250                 testName, chunkSize, u_errorName(errorCode), u_errorName(expectCode));
   2251     } else if(targetLength!=expectTargetLength) {
   2252         log_err("ucnv_convertEx(%s) chunk[%d] writes %d bytes instead of %d\n",
   2253                 testName, chunkSize, targetLength, expectTargetLength);
   2254     } else if(memcmp(targetBuffer, expectTarget, targetLength)!=0) {
   2255         log_err("ucnv_convertEx(%s) chunk[%d] writes different bytes than expected\n",
   2256                 testName, chunkSize);
   2257     }
   2258 }
   2259 
   2260 static void
   2261 convertExMultiStreaming(UConverter *srcCnv, UConverter *targetCnv,
   2262                         const char *src, int32_t srcLength,
   2263                         const char *expectTarget, int32_t expectTargetLength,
   2264                         const char *testName,
   2265                         UErrorCode expectCode) {
   2266     convertExStreaming(srcCnv, targetCnv,
   2267                        src, srcLength,
   2268                        expectTarget, expectTargetLength,
   2269                        1, testName, expectCode);
   2270     convertExStreaming(srcCnv, targetCnv,
   2271                        src, srcLength,
   2272                        expectTarget, expectTargetLength,
   2273                        3, testName, expectCode);
   2274     convertExStreaming(srcCnv, targetCnv,
   2275                        src, srcLength,
   2276                        expectTarget, expectTargetLength,
   2277                        7, testName, expectCode);
   2278 }
   2279 
   2280 static void TestConvertEx() {
   2281 #if !UCONFIG_NO_LEGACY_CONVERSION
   2282     static const uint8_t
   2283     utf8[]={
   2284         /* 4e00           30a1              ff61              0410 */
   2285         0xe4, 0xb8, 0x80, 0xe3, 0x82, 0xa1, 0xef, 0xbd, 0xa1, 0xd0, 0x90
   2286     },
   2287     shiftJIS[]={
   2288         0x88, 0xea, 0x83, 0x40, 0xa1, 0x84, 0x40
   2289     },
   2290     errorTarget[]={
   2291         /*
   2292          * expected output when converting shiftJIS[] from UTF-8 to Shift-JIS:
   2293          * SUB, SUB, 0x40, SUB, SUB, 0x40
   2294          */
   2295         0xfc, 0xfc, 0xfc, 0xfc, 0x40, 0xfc, 0xfc, 0xfc, 0xfc, 0x40
   2296     };
   2297 
   2298     char srcBuffer[100], targetBuffer[100];
   2299 
   2300     const char *src;
   2301     char *target;
   2302 
   2303     UChar pivotBuffer[100];
   2304     UChar *pivotSource, *pivotTarget;
   2305 
   2306     UConverter *cnv1, *cnv2;
   2307     UErrorCode errorCode;
   2308 
   2309     errorCode=U_ZERO_ERROR;
   2310     cnv1=ucnv_open("UTF-8", &errorCode);
   2311     if(U_FAILURE(errorCode)) {
   2312         log_err("unable to open a UTF-8 converter - %s\n", u_errorName(errorCode));
   2313         return;
   2314     }
   2315 
   2316     cnv2=ucnv_open("Shift-JIS", &errorCode);
   2317     if(U_FAILURE(errorCode)) {
   2318         log_data_err("unable to open a Shift-JIS converter - %s\n", u_errorName(errorCode));
   2319         ucnv_close(cnv1);
   2320         return;
   2321     }
   2322 
   2323     /* test ucnv_convertEx() with streaming conversion style */
   2324     convertExMultiStreaming(cnv1, cnv2,
   2325         (const char *)utf8, sizeof(utf8), (const char *)shiftJIS, sizeof(shiftJIS),
   2326         "UTF-8 -> Shift-JIS", U_ZERO_ERROR);
   2327 
   2328     convertExMultiStreaming(cnv2, cnv1,
   2329         (const char *)shiftJIS, sizeof(shiftJIS), (const char *)utf8, sizeof(utf8),
   2330         "Shift-JIS -> UTF-8", U_ZERO_ERROR);
   2331 
   2332     /* U_ZERO_ERROR because by default the SUB callbacks are set */
   2333     convertExMultiStreaming(cnv1, cnv2,
   2334         (const char *)shiftJIS, sizeof(shiftJIS), (const char *)errorTarget, sizeof(errorTarget),
   2335         "shiftJIS[] UTF-8 -> Shift-JIS", U_ZERO_ERROR);
   2336 
   2337     /* test some simple conversions */
   2338 
   2339     /* NUL-terminated source and target */
   2340     errorCode=U_STRING_NOT_TERMINATED_WARNING;
   2341     memcpy(srcBuffer, utf8, sizeof(utf8));
   2342     srcBuffer[sizeof(utf8)]=0;
   2343     src=srcBuffer;
   2344     target=targetBuffer;
   2345     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2346                    NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
   2347     if( errorCode!=U_ZERO_ERROR ||
   2348         target-targetBuffer!=sizeof(shiftJIS) ||
   2349         *target!=0 ||
   2350         memcmp(targetBuffer, shiftJIS, sizeof(shiftJIS))!=0
   2351     ) {
   2352         log_err("ucnv_convertEx(simple UTF-8 -> Shift_JIS) fails: %s - writes %d bytes, expect %d\n",
   2353                 u_errorName(errorCode), target-targetBuffer, sizeof(shiftJIS));
   2354     }
   2355 
   2356     /* NUL-terminated source and U_STRING_NOT_TERMINATED_WARNING */
   2357     errorCode=U_AMBIGUOUS_ALIAS_WARNING;
   2358     memset(targetBuffer, 0xff, sizeof(targetBuffer));
   2359     src=srcBuffer;
   2360     target=targetBuffer;
   2361     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(shiftJIS), &src, NULL,
   2362                    NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
   2363     if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
   2364         target-targetBuffer!=sizeof(shiftJIS) ||
   2365         *target!=(char)0xff ||
   2366         memcmp(targetBuffer, shiftJIS, sizeof(shiftJIS))!=0
   2367     ) {
   2368         log_err("ucnv_convertEx(simple UTF-8 -> Shift_JIS) fails: %s, expect U_STRING_NOT_TERMINATED_WARNING - writes %d bytes, expect %d\n",
   2369                 u_errorName(errorCode), target-targetBuffer, sizeof(shiftJIS));
   2370     }
   2371 
   2372     /* bad arguments */
   2373     errorCode=U_MESSAGE_PARSE_ERROR;
   2374     src=srcBuffer;
   2375     target=targetBuffer;
   2376     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2377                    NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
   2378     if(errorCode!=U_MESSAGE_PARSE_ERROR) {
   2379         log_err("ucnv_convertEx(U_MESSAGE_PARSE_ERROR) sets %s\n", u_errorName(errorCode));
   2380     }
   2381 
   2382     /* pivotLimit==pivotStart */
   2383     errorCode=U_ZERO_ERROR;
   2384     pivotSource=pivotTarget=pivotBuffer;
   2385     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2386                    pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer, TRUE, TRUE, &errorCode);
   2387     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2388         log_err("ucnv_convertEx(pivotLimit==pivotStart) sets %s\n", u_errorName(errorCode));
   2389     }
   2390 
   2391     /* *pivotSource==NULL */
   2392     errorCode=U_ZERO_ERROR;
   2393     pivotSource=NULL;
   2394     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2395                    pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, TRUE, &errorCode);
   2396     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2397         log_err("ucnv_convertEx(*pivotSource==NULL) sets %s\n", u_errorName(errorCode));
   2398     }
   2399 
   2400     /* *source==NULL */
   2401     errorCode=U_ZERO_ERROR;
   2402     src=NULL;
   2403     pivotSource=pivotBuffer;
   2404     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2405                    pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, TRUE, &errorCode);
   2406     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2407         log_err("ucnv_convertEx(*source==NULL) sets %s\n", u_errorName(errorCode));
   2408     }
   2409 
   2410     /* streaming conversion without a pivot buffer */
   2411     errorCode=U_ZERO_ERROR;
   2412     src=srcBuffer;
   2413     pivotSource=pivotBuffer;
   2414     ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
   2415                    NULL, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, FALSE, &errorCode);
   2416     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2417         log_err("ucnv_convertEx(pivotStart==NULL) sets %s\n", u_errorName(errorCode));
   2418     }
   2419 
   2420     ucnv_close(cnv1);
   2421     ucnv_close(cnv2);
   2422 #endif
   2423 }
   2424 
   2425 /* Test illegal UTF-8 input: Data and functions for TestConvertExFromUTF8(). */
   2426 static const char *const badUTF8[]={
   2427     /* trail byte */
   2428     "\x80",
   2429 
   2430     /* truncated multi-byte sequences */
   2431     "\xd0",
   2432     "\xe0",
   2433     "\xe1",
   2434     "\xed",
   2435     "\xee",
   2436     "\xf0",
   2437     "\xf1",
   2438     "\xf4",
   2439     "\xf8",
   2440     "\xfc",
   2441 
   2442     "\xe0\x80",
   2443     "\xe0\xa0",
   2444     "\xe1\x80",
   2445     "\xed\x80",
   2446     "\xed\xa0",
   2447     "\xee\x80",
   2448     "\xf0\x80",
   2449     "\xf0\x90",
   2450     "\xf1\x80",
   2451     "\xf4\x80",
   2452     "\xf4\x90",
   2453     "\xf8\x80",
   2454     "\xfc\x80",
   2455 
   2456     "\xf0\x80\x80",
   2457     "\xf0\x90\x80",
   2458     "\xf1\x80\x80",
   2459     "\xf4\x80\x80",
   2460     "\xf4\x90\x80",
   2461     "\xf8\x80\x80",
   2462     "\xfc\x80\x80",
   2463 
   2464     "\xf8\x80\x80\x80",
   2465     "\xfc\x80\x80\x80",
   2466 
   2467     "\xfc\x80\x80\x80\x80",
   2468 
   2469     /* complete sequences but non-shortest forms or out of range etc. */
   2470     "\xc0\x80",
   2471     "\xe0\x80\x80",
   2472     "\xed\xa0\x80",
   2473     "\xf0\x80\x80\x80",
   2474     "\xf4\x90\x80\x80",
   2475     "\xf8\x80\x80\x80\x80",
   2476     "\xfc\x80\x80\x80\x80\x80",
   2477     "\xfe",
   2478     "\xff"
   2479 };
   2480 
   2481 /* get some character that can be converted and convert it */
   2482 static UBool getTestChar(UConverter *cnv, const char *converterName,
   2483                          char charUTF8[4], int32_t *pCharUTF8Length,
   2484                          char char0[8], int32_t *pChar0Length,
   2485                          char char1[8], int32_t *pChar1Length) {
   2486     UChar utf16[U16_MAX_LENGTH];
   2487     int32_t utf16Length;
   2488 
   2489     const UChar *utf16Source;
   2490     char *target;
   2491 
   2492     USet *set;
   2493     UChar32 c;
   2494     UErrorCode errorCode;
   2495 
   2496     errorCode=U_ZERO_ERROR;
   2497     set=uset_open(1, 0);
   2498     ucnv_getUnicodeSet(cnv, set, UCNV_ROUNDTRIP_SET, &errorCode);
   2499     c=uset_charAt(set, uset_size(set)/2);
   2500     uset_close(set);
   2501 
   2502     utf16Length=0;
   2503     U16_APPEND_UNSAFE(utf16, utf16Length, c);
   2504     *pCharUTF8Length=0;
   2505     U8_APPEND_UNSAFE(charUTF8, *pCharUTF8Length, c);
   2506 
   2507     utf16Source=utf16;
   2508     target=char0;
   2509     ucnv_fromUnicode(cnv,
   2510                      &target, char0+sizeof(char0),
   2511                      &utf16Source, utf16+utf16Length,
   2512                      NULL, FALSE, &errorCode);
   2513     *pChar0Length=(int32_t)(target-char0);
   2514 
   2515     utf16Source=utf16;
   2516     target=char1;
   2517     ucnv_fromUnicode(cnv,
   2518                      &target, char1+sizeof(char1),
   2519                      &utf16Source, utf16+utf16Length,
   2520                      NULL, FALSE, &errorCode);
   2521     *pChar1Length=(int32_t)(target-char1);
   2522 
   2523     if(U_FAILURE(errorCode)) {
   2524         log_err("unable to get test character for %s - %s\n", converterName, u_errorName(errorCode));
   2525         return FALSE;
   2526     }
   2527     return TRUE;
   2528 }
   2529 
   2530 static void testFromTruncatedUTF8(UConverter *utf8Cnv, UConverter *cnv, const char *converterName,
   2531                                   char charUTF8[4], int32_t charUTF8Length,
   2532                                   char char0[8], int32_t char0Length,
   2533                                   char char1[8], int32_t char1Length) {
   2534     char utf8[16];
   2535     int32_t utf8Length;
   2536 
   2537     char output[16];
   2538     int32_t outputLength;
   2539 
   2540     char invalidChars[8];
   2541     int8_t invalidLength;
   2542 
   2543     const char *source;
   2544     char *target;
   2545 
   2546     UChar pivotBuffer[8];
   2547     UChar *pivotSource, *pivotTarget;
   2548 
   2549     UErrorCode errorCode;
   2550     int32_t i;
   2551 
   2552     /* test truncated sequences */
   2553     errorCode=U_ZERO_ERROR;
   2554     ucnv_setToUCallBack(utf8Cnv, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &errorCode);
   2555 
   2556     memcpy(utf8, charUTF8, charUTF8Length);
   2557 
   2558     for(i=0; i<LENGTHOF(badUTF8); ++i) {
   2559         /* truncated sequence? */
   2560         int32_t length=strlen(badUTF8[i]);
   2561         if(length>=(1+U8_COUNT_TRAIL_BYTES(badUTF8[i][0]))) {
   2562             continue;
   2563         }
   2564 
   2565         /* assemble a string with the test character and the truncated sequence */
   2566         memcpy(utf8+charUTF8Length, badUTF8[i], length);
   2567         utf8Length=charUTF8Length+length;
   2568 
   2569         /* convert and check the invalidChars */
   2570         source=utf8;
   2571         target=output;
   2572         pivotSource=pivotTarget=pivotBuffer;
   2573         errorCode=U_ZERO_ERROR;
   2574         ucnv_convertEx(cnv, utf8Cnv,
   2575                        &target, output+sizeof(output),
   2576                        &source, utf8+utf8Length,
   2577                        pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+LENGTHOF(pivotBuffer),
   2578                        TRUE, TRUE, /* reset & flush */
   2579                        &errorCode);
   2580         outputLength=(int32_t)(target-output);
   2581         if(errorCode!=U_TRUNCATED_CHAR_FOUND || pivotSource!=pivotBuffer) {
   2582             log_err("unexpected error %s from %s badUTF8[%ld]\n", u_errorName(errorCode), converterName, (long)i);
   2583             continue;
   2584         }
   2585 
   2586         errorCode=U_ZERO_ERROR;
   2587         invalidLength=(int8_t)sizeof(invalidChars);
   2588         ucnv_getInvalidChars(utf8Cnv, invalidChars, &invalidLength, &errorCode);
   2589         if(invalidLength!=length || 0!=memcmp(invalidChars, badUTF8[i], length)) {
   2590             log_err("wrong invalidChars from %s badUTF8[%ld]\n", converterName, (long)i);
   2591         }
   2592     }
   2593 }
   2594 
   2595 static void testFromBadUTF8(UConverter *utf8Cnv, UConverter *cnv, const char *converterName,
   2596                             char charUTF8[4], int32_t charUTF8Length,
   2597                             char char0[8], int32_t char0Length,
   2598                             char char1[8], int32_t char1Length) {
   2599     char utf8[600], expect[600];
   2600     int32_t utf8Length, expectLength;
   2601 
   2602     char testName[32];
   2603 
   2604     UErrorCode errorCode;
   2605     int32_t i;
   2606 
   2607     errorCode=U_ZERO_ERROR;
   2608     ucnv_setToUCallBack(utf8Cnv, UCNV_TO_U_CALLBACK_SKIP, NULL, NULL, NULL, &errorCode);
   2609 
   2610     /*
   2611      * assemble an input string with the test character between each
   2612      * bad sequence,
   2613      * and an expected string with repeated test character output
   2614      */
   2615     memcpy(utf8, charUTF8, charUTF8Length);
   2616     utf8Length=charUTF8Length;
   2617 
   2618     memcpy(expect, char0, char0Length);
   2619     expectLength=char0Length;
   2620 
   2621     for(i=0; i<LENGTHOF(badUTF8); ++i) {
   2622         int32_t length=strlen(badUTF8[i]);
   2623         memcpy(utf8+utf8Length, badUTF8[i], length);
   2624         utf8Length+=length;
   2625 
   2626         memcpy(utf8+utf8Length, charUTF8, charUTF8Length);
   2627         utf8Length+=charUTF8Length;
   2628 
   2629         memcpy(expect+expectLength, char1, char1Length);
   2630         expectLength+=char1Length;
   2631     }
   2632 
   2633     /* expect that each bad UTF-8 sequence is detected and skipped */
   2634     strcpy(testName, "from bad UTF-8 to ");
   2635     strcat(testName, converterName);
   2636 
   2637     convertExMultiStreaming(utf8Cnv, cnv,
   2638                             utf8, utf8Length,
   2639                             expect, expectLength,
   2640                             testName,
   2641                             U_ZERO_ERROR);
   2642 }
   2643 
   2644 /* Test illegal UTF-8 input. */
   2645 static void TestConvertExFromUTF8() {
   2646     static const char *const converterNames[]={
   2647 #if !UCONFIG_NO_LEGACY_CONVERSION
   2648         "windows-1252",
   2649         "shift-jis",
   2650 #endif
   2651         "us-ascii",
   2652         "iso-8859-1",
   2653         "utf-8"
   2654     };
   2655 
   2656     UConverter *utf8Cnv, *cnv;
   2657     UErrorCode errorCode;
   2658     int32_t i;
   2659 
   2660     /* fromUnicode versions of some character, from initial state and later */
   2661     char charUTF8[4], char0[8], char1[8];
   2662     int32_t charUTF8Length, char0Length, char1Length;
   2663 
   2664     errorCode=U_ZERO_ERROR;
   2665     utf8Cnv=ucnv_open("UTF-8", &errorCode);
   2666     if(U_FAILURE(errorCode)) {
   2667         log_data_err("unable to open UTF-8 converter - %s\n", u_errorName(errorCode));
   2668         return;
   2669     }
   2670 
   2671     for(i=0; i<LENGTHOF(converterNames); ++i) {
   2672         errorCode=U_ZERO_ERROR;
   2673         cnv=ucnv_open(converterNames[i], &errorCode);
   2674         if(U_FAILURE(errorCode)) {
   2675             log_data_err("unable to open %s converter - %s\n", converterNames[i], u_errorName(errorCode));
   2676             continue;
   2677         }
   2678         if(!getTestChar(cnv, converterNames[i], charUTF8, &charUTF8Length, char0, &char0Length, char1, &char1Length)) {
   2679             continue;
   2680         }
   2681         testFromTruncatedUTF8(utf8Cnv, cnv, converterNames[i], charUTF8, charUTF8Length, char0, char0Length, char1, char1Length);
   2682         testFromBadUTF8(utf8Cnv, cnv, converterNames[i], charUTF8, charUTF8Length, char0, char0Length, char1, char1Length);
   2683         ucnv_close(cnv);
   2684     }
   2685     ucnv_close(utf8Cnv);
   2686 }
   2687 
   2688 static void TestConvertExFromUTF8_C5F0() {
   2689     static const char *const converterNames[]={
   2690 #if !UCONFIG_NO_LEGACY_CONVERSION
   2691         "windows-1251",
   2692         "shift-jis",
   2693 #endif
   2694         "us-ascii",
   2695         "iso-8859-1",
   2696         "utf-8"
   2697     };
   2698 
   2699     UConverter *utf8Cnv, *cnv;
   2700     UErrorCode errorCode;
   2701     int32_t i;
   2702 
   2703     static const char bad_utf8[2]={ (char)0xC5, (char)0xF0 };
   2704     /* Expect "&#65533;&#65533;" (2x U+FFFD as decimal NCRs) */
   2705     static const char twoNCRs[16]={
   2706         0x26, 0x23, 0x36, 0x35, 0x35, 0x33, 0x33, 0x3B,
   2707         0x26, 0x23, 0x36, 0x35, 0x35, 0x33, 0x33, 0x3B
   2708     };
   2709     static const char twoFFFD[6]={
   2710         (char)0xef, (char)0xbf, (char)0xbd,
   2711         (char)0xef, (char)0xbf, (char)0xbd
   2712     };
   2713     const char *expected;
   2714     int32_t expectedLength;
   2715     char dest[20];  /* longer than longest expectedLength */
   2716 
   2717     const char *src;
   2718     char *target;
   2719 
   2720     UChar pivotBuffer[128];
   2721     UChar *pivotSource, *pivotTarget;
   2722 
   2723     errorCode=U_ZERO_ERROR;
   2724     utf8Cnv=ucnv_open("UTF-8", &errorCode);
   2725     if(U_FAILURE(errorCode)) {
   2726         log_data_err("unable to open UTF-8 converter - %s\n", u_errorName(errorCode));
   2727         return;
   2728     }
   2729 
   2730     for(i=0; i<LENGTHOF(converterNames); ++i) {
   2731         errorCode=U_ZERO_ERROR;
   2732         cnv=ucnv_open(converterNames[i], &errorCode);
   2733         ucnv_setFromUCallBack(cnv, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_XML_DEC,
   2734                               NULL, NULL, &errorCode);
   2735         if(U_FAILURE(errorCode)) {
   2736             log_data_err("unable to open %s converter - %s\n",
   2737                          converterNames[i], u_errorName(errorCode));
   2738             continue;
   2739         }
   2740         src=bad_utf8;
   2741         target=dest;
   2742         uprv_memset(dest, 9, sizeof(dest));
   2743         if(i==LENGTHOF(converterNames)-1) {
   2744             /* conversion to UTF-8 yields two U+FFFD directly */
   2745             expected=twoFFFD;
   2746             expectedLength=6;
   2747         } else {
   2748             /* conversion to a non-Unicode charset yields two NCRs */
   2749             expected=twoNCRs;
   2750             expectedLength=16;
   2751         }
   2752         pivotBuffer[0]=0;
   2753         pivotBuffer[1]=1;
   2754         pivotBuffer[2]=2;
   2755         pivotSource=pivotTarget=pivotBuffer;
   2756         ucnv_convertEx(
   2757             cnv, utf8Cnv,
   2758             &target, dest+expectedLength,
   2759             &src, bad_utf8+sizeof(bad_utf8),
   2760             pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+LENGTHOF(pivotBuffer),
   2761             TRUE, TRUE, &errorCode);
   2762         if( errorCode!=U_STRING_NOT_TERMINATED_WARNING || src!=bad_utf8+2 ||
   2763             target!=dest+expectedLength || 0!=uprv_memcmp(dest, expected, expectedLength) ||
   2764             dest[expectedLength]!=9
   2765         ) {
   2766             log_err("ucnv_convertEx(UTF-8 C5 F0 -> %s/decimal NCRs) failed\n", converterNames[i]);
   2767         }
   2768         ucnv_close(cnv);
   2769     }
   2770     ucnv_close(utf8Cnv);
   2771 }
   2772 
   2773 static void
   2774 TestConvertAlgorithmic() {
   2775 #if !UCONFIG_NO_LEGACY_CONVERSION
   2776     static const uint8_t
   2777     utf8[]={
   2778         /* 4e00           30a1              ff61              0410 */
   2779         0xe4, 0xb8, 0x80, 0xe3, 0x82, 0xa1, 0xef, 0xbd, 0xa1, 0xd0, 0x90
   2780     },
   2781     shiftJIS[]={
   2782         0x88, 0xea, 0x83, 0x40, 0xa1, 0x84, 0x40
   2783     },
   2784   /*errorTarget[]={*/
   2785         /*
   2786          * expected output when converting shiftJIS[] from UTF-8 to Shift-JIS:
   2787          * SUB, SUB, 0x40, SUB, SUB, 0x40
   2788          */
   2789   /* 0x81, 0xa1, 0x81, 0xa1, 0x40, 0x81, 0xa1, 0x81, 0xa1, 0x40*/
   2790   /*},*/
   2791     utf16[]={
   2792         0xfe, 0xff /* BOM only, no text */
   2793     },
   2794     utf32[]={
   2795         0xff, 0xfe, 0, 0 /* BOM only, no text */
   2796     };
   2797 
   2798     char target[100], utf8NUL[100], shiftJISNUL[100];
   2799 
   2800     UConverter *cnv;
   2801     UErrorCode errorCode;
   2802 
   2803     int32_t length;
   2804 
   2805     errorCode=U_ZERO_ERROR;
   2806     cnv=ucnv_open("Shift-JIS", &errorCode);
   2807     if(U_FAILURE(errorCode)) {
   2808         log_data_err("unable to open a Shift-JIS converter - %s\n", u_errorName(errorCode));
   2809         ucnv_close(cnv);
   2810         return;
   2811     }
   2812 
   2813     memcpy(utf8NUL, utf8, sizeof(utf8));
   2814     utf8NUL[sizeof(utf8)]=0;
   2815     memcpy(shiftJISNUL, shiftJIS, sizeof(shiftJIS));
   2816     shiftJISNUL[sizeof(shiftJIS)]=0;
   2817 
   2818     /*
   2819      * The to/from algorithmic convenience functions share a common implementation,
   2820      * so we need not test all permutations of them.
   2821      */
   2822 
   2823     /* length in, not terminated out */
   2824     errorCode=U_ZERO_ERROR;
   2825     length=ucnv_fromAlgorithmic(cnv, UCNV_UTF8, target, sizeof(shiftJIS), (const char *)utf8, sizeof(utf8), &errorCode);
   2826     if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
   2827         length!=sizeof(shiftJIS) ||
   2828         memcmp(target, shiftJIS, length)!=0
   2829     ) {
   2830         log_err("ucnv_fromAlgorithmic(UTF-8 -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect %d\n",
   2831                 u_errorName(errorCode), length, sizeof(shiftJIS));
   2832     }
   2833 
   2834     /* terminated in and out */
   2835     memset(target, 0x55, sizeof(target));
   2836     errorCode=U_STRING_NOT_TERMINATED_WARNING;
   2837     length=ucnv_toAlgorithmic(UCNV_UTF8, cnv, target, sizeof(target), shiftJISNUL, -1, &errorCode);
   2838     if( errorCode!=U_ZERO_ERROR ||
   2839         length!=sizeof(utf8) ||
   2840         memcmp(target, utf8, length)!=0
   2841     ) {
   2842         log_err("ucnv_toAlgorithmic(Shift-JIS -> UTF-8) fails (%s expect U_ZERO_ERROR), returns %d expect %d\n",
   2843                 u_errorName(errorCode), length, sizeof(shiftJIS));
   2844     }
   2845 
   2846     /* empty string, some target buffer */
   2847     errorCode=U_STRING_NOT_TERMINATED_WARNING;
   2848     length=ucnv_toAlgorithmic(UCNV_UTF8, cnv, target, sizeof(target), shiftJISNUL, 0, &errorCode);
   2849     if( errorCode!=U_ZERO_ERROR ||
   2850         length!=0
   2851     ) {
   2852         log_err("ucnv_toAlgorithmic(empty string -> UTF-8) fails (%s expect U_ZERO_ERROR), returns %d expect 0\n",
   2853                 u_errorName(errorCode), length);
   2854     }
   2855 
   2856     /* pseudo-empty string, no target buffer */
   2857     errorCode=U_ZERO_ERROR;
   2858     length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, (const char *)utf16, 2, &errorCode);
   2859     if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
   2860         length!=0
   2861     ) {
   2862         log_err("ucnv_fromAlgorithmic(UTF-16 only BOM -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect 0\n",
   2863                 u_errorName(errorCode), length);
   2864     }
   2865 
   2866     errorCode=U_ZERO_ERROR;
   2867     length=ucnv_fromAlgorithmic(cnv, UCNV_UTF32, target, 0, (const char *)utf32, 4, &errorCode);
   2868     if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
   2869         length!=0
   2870     ) {
   2871         log_err("ucnv_fromAlgorithmic(UTF-32 only BOM -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect 0\n",
   2872                 u_errorName(errorCode), length);
   2873     }
   2874 
   2875     /* bad arguments */
   2876     errorCode=U_MESSAGE_PARSE_ERROR;
   2877     length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, (const char *)utf16, 2, &errorCode);
   2878     if(errorCode!=U_MESSAGE_PARSE_ERROR) {
   2879         log_err("ucnv_fromAlgorithmic(U_MESSAGE_PARSE_ERROR) sets %s\n", u_errorName(errorCode));
   2880     }
   2881 
   2882     /* source==NULL */
   2883     errorCode=U_ZERO_ERROR;
   2884     length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, NULL, 2, &errorCode);
   2885     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2886         log_err("ucnv_fromAlgorithmic(source==NULL) sets %s\n", u_errorName(errorCode));
   2887     }
   2888 
   2889     /* illegal alg. type */
   2890     errorCode=U_ZERO_ERROR;
   2891     length=ucnv_fromAlgorithmic(cnv, (UConverterType)99, target, 0, (const char *)utf16, 2, &errorCode);
   2892     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
   2893         log_err("ucnv_fromAlgorithmic(illegal alg. type) sets %s\n", u_errorName(errorCode));
   2894     }
   2895 ucnv_close(cnv);
   2896 #endif
   2897 }
   2898 
   2899 static void TestLMBCSMaxChar(void) {
   2900     static const struct {
   2901         int8_t maxSize;
   2902         const char *name;
   2903     } converter[] = {
   2904         /* some non-LMBCS converters - perfect test setup here */
   2905         { 1, "US-ASCII"},
   2906         { 1, "ISO-8859-1"},
   2907 
   2908         { 2, "UTF-16"},
   2909         { 2, "UTF-16BE"},
   2910         { 3, "UTF-8"},
   2911         { 3, "CESU-8"},
   2912         { 3, "SCSU"},
   2913         { 4, "UTF-32"},
   2914         { 4, "UTF-7"},
   2915         { 4, "IMAP-mailbox-name"},
   2916         { 4, "BOCU-1"},
   2917 
   2918         { 1, "windows-1256"},
   2919         { 2, "Shift-JIS"},
   2920         { 2, "ibm-16684"},
   2921         { 3, "ibm-930"},
   2922         { 3, "ibm-1390"},
   2923         { 4, "*test3"},
   2924         { 16,"*test4"},
   2925 
   2926         { 4, "ISCII"},
   2927         { 4, "HZ"},
   2928 
   2929         { 3, "ISO-2022"},
   2930         { 3, "ISO-2022-KR"},
   2931         { 6, "ISO-2022-JP"},
   2932         { 8, "ISO-2022-CN"},
   2933 
   2934         /* LMBCS */
   2935         { 3, "LMBCS-1"},
   2936         { 3, "LMBCS-2"},
   2937         { 3, "LMBCS-3"},
   2938         { 3, "LMBCS-4"},
   2939         { 3, "LMBCS-5"},
   2940         { 3, "LMBCS-6"},
   2941         { 3, "LMBCS-8"},
   2942         { 3, "LMBCS-11"},
   2943         { 3, "LMBCS-16"},
   2944         { 3, "LMBCS-17"},
   2945         { 3, "LMBCS-18"},
   2946         { 3, "LMBCS-19"}
   2947     };
   2948     int32_t idx;
   2949 
   2950     for (idx = 0; idx < LENGTHOF(converter); idx++) {
   2951         UErrorCode status = U_ZERO_ERROR;
   2952         UConverter *cnv = cnv_open(converter[idx].name, &status);
   2953         if (U_FAILURE(status)) {
   2954             continue;
   2955         }
   2956         if (converter[idx].maxSize != ucnv_getMaxCharSize(cnv)) {
   2957             log_err("error: ucnv_getMaxCharSize(%s) expected %d, got %d\n",
   2958                 converter[idx].name, converter[idx].maxSize, ucnv_getMaxCharSize(cnv));
   2959         }
   2960         ucnv_close(cnv);
   2961     }
   2962 
   2963     /* mostly test that the macro compiles */
   2964     if(UCNV_GET_MAX_BYTES_FOR_STRING(1, 2)<10) {
   2965         log_err("error UCNV_GET_MAX_BYTES_FOR_STRING(1, 2)<10\n");
   2966     }
   2967 }
   2968 
   2969 
   2970 static void TestJ1968(void) {
   2971     UErrorCode err = U_ZERO_ERROR;
   2972     UConverter *cnv;
   2973     char myConvName[] = "My really really really really really really really really really really really"
   2974                           " really really really really really really really really really really really"
   2975                           " really really really really really really really really long converter name";
   2976     UChar myConvNameU[sizeof(myConvName)];
   2977 
   2978     u_charsToUChars(myConvName, myConvNameU, sizeof(myConvName));
   2979 
   2980     err = U_ZERO_ERROR;
   2981     myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH+1] = 0;
   2982     cnv = ucnv_openU(myConvNameU, &err);
   2983     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   2984         log_err("1U) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   2985     }
   2986 
   2987     err = U_ZERO_ERROR;
   2988     myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH] = 0;
   2989     cnv = ucnv_openU(myConvNameU, &err);
   2990     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   2991         log_err("2U) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   2992     }
   2993 
   2994     err = U_ZERO_ERROR;
   2995     myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = 0;
   2996     cnv = ucnv_openU(myConvNameU, &err);
   2997     if (cnv || err != U_FILE_ACCESS_ERROR) {
   2998         log_err("3U) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
   2999     }
   3000 
   3001 
   3002 
   3003 
   3004     err = U_ZERO_ERROR;
   3005     cnv = ucnv_open(myConvName, &err);
   3006     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   3007         log_err("1) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   3008     }
   3009 
   3010     err = U_ZERO_ERROR;
   3011     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH] = ',';
   3012     cnv = ucnv_open(myConvName, &err);
   3013     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   3014         log_err("2) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   3015     }
   3016 
   3017     err = U_ZERO_ERROR;
   3018     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ',';
   3019     cnv = ucnv_open(myConvName, &err);
   3020     if (cnv || err != U_FILE_ACCESS_ERROR) {
   3021         log_err("3) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
   3022     }
   3023 
   3024     err = U_ZERO_ERROR;
   3025     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ',';
   3026     strncpy(myConvName + UCNV_MAX_CONVERTER_NAME_LENGTH, "locale=", 7);
   3027     cnv = ucnv_open(myConvName, &err);
   3028     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   3029         log_err("4) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   3030     }
   3031 
   3032     /* The comma isn't really a part of the converter name. */
   3033     err = U_ZERO_ERROR;
   3034     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH] = 0;
   3035     cnv = ucnv_open(myConvName, &err);
   3036     if (cnv || err != U_FILE_ACCESS_ERROR) {
   3037         log_err("5) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
   3038     }
   3039 
   3040     err = U_ZERO_ERROR;
   3041     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ' ';
   3042     cnv = ucnv_open(myConvName, &err);
   3043     if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
   3044         log_err("6) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
   3045     }
   3046 
   3047     err = U_ZERO_ERROR;
   3048     myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = 0;
   3049     cnv = ucnv_open(myConvName, &err);
   3050     if (cnv || err != U_FILE_ACCESS_ERROR) {
   3051         log_err("7) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
   3052     }
   3053 
   3054 }
   3055 
   3056 #if !UCONFIG_NO_LEGACY_CONVERSION
   3057 static void
   3058 testSwap(const char *name, UBool swap) {
   3059     /*
   3060      * Test Unicode text.
   3061      * Contains characters that are the highest for some of the
   3062      * tested conversions, to make sure that the ucnvmbcs.c code that modifies the
   3063      * tables copies the entire tables.
   3064      */
   3065     static const UChar text[]={
   3066         0x61, 0xd, 0x62, 0xa, 0x4e00, 0x3000, 0xfffd, 0xa, 0x20, 0x85, 0xff5e, 0x7a
   3067     };
   3068 
   3069     UChar uNormal[32], uSwapped[32];
   3070     char normal[32], swapped[32];
   3071     const UChar *pcu;
   3072     UChar *pu;
   3073     char *pc;
   3074     int32_t i, normalLength, swappedLength;
   3075     UChar u;
   3076     char c;
   3077 
   3078     const char *swappedName;
   3079     UConverter *cnv, *swapCnv;
   3080     UErrorCode errorCode;
   3081 
   3082     /* if the swap flag is FALSE, then the test encoding is not EBCDIC and must not swap */
   3083 
   3084     /* open both the normal and the LF/NL-swapping converters */
   3085     strcpy(swapped, name);
   3086     strcat(swapped, UCNV_SWAP_LFNL_OPTION_STRING);
   3087 
   3088     errorCode=U_ZERO_ERROR;
   3089     swapCnv=ucnv_open(swapped, &errorCode);
   3090     cnv=ucnv_open(name, &errorCode);
   3091     if(U_FAILURE(errorCode)) {
   3092         log_data_err("TestEBCDICSwapLFNL error: unable to open %s or %s (%s)\n", name, swapped, u_errorName(errorCode));
   3093         goto cleanup;
   3094     }
   3095 
   3096     /* the name must contain the swap option if and only if we expect the converter to swap */
   3097     swappedName=ucnv_getName(swapCnv, &errorCode);
   3098     if(U_FAILURE(errorCode)) {
   3099         log_err("TestEBCDICSwapLFNL error: ucnv_getName(%s,swaplfnl) failed (%s)\n", name, u_errorName(errorCode));
   3100         goto cleanup;
   3101     }
   3102 
   3103     pc=strstr(swappedName, UCNV_SWAP_LFNL_OPTION_STRING);
   3104     if(swap != (pc!=NULL)) {
   3105         log_err("TestEBCDICSwapLFNL error: ucnv_getName(%s,swaplfnl)=%s should (%d) contain 'swaplfnl'\n", name, swappedName, swap);
   3106         goto cleanup;
   3107     }
   3108 
   3109     /* convert to EBCDIC */
   3110     pcu=text;
   3111     pc=normal;
   3112     ucnv_fromUnicode(cnv, &pc, normal+LENGTHOF(normal), &pcu, text+LENGTHOF(text), NULL, TRUE, &errorCode);
   3113     normalLength=(int32_t)(pc-normal);
   3114 
   3115     pcu=text;
   3116     pc=swapped;
   3117     ucnv_fromUnicode(swapCnv, &pc, swapped+LENGTHOF(swapped), &pcu, text+LENGTHOF(text), NULL, TRUE, &errorCode);
   3118     swappedLength=(int32_t)(pc-swapped);
   3119 
   3120     if(U_FAILURE(errorCode)) {
   3121         log_err("TestEBCDICSwapLFNL error converting to %s - (%s)\n", name, u_errorName(errorCode));
   3122         goto cleanup;
   3123     }
   3124 
   3125     /* compare EBCDIC output */
   3126     if(normalLength!=swappedLength) {
   3127         log_err("TestEBCDICSwapLFNL error converting to %s - output lengths %d vs. %d\n", name, normalLength, swappedLength);
   3128         goto cleanup;
   3129     }
   3130     for(i=0; i<normalLength; ++i) {
   3131         /* swap EBCDIC LF/NL for comparison */
   3132         c=normal[i];
   3133         if(swap) {
   3134             if(c==0x15) {
   3135                 c=0x25;
   3136             } else if(c==0x25) {
   3137                 c=0x15;
   3138             }
   3139         }
   3140 
   3141         if(c!=swapped[i]) {
   3142             log_err("TestEBCDICSwapLFNL error converting to %s - did not swap properly, output[%d]=0x%02x\n", name, i, (uint8_t)swapped[i]);
   3143             goto cleanup;
   3144         }
   3145     }
   3146 
   3147     /* convert back to Unicode (may not roundtrip) */
   3148     pc=normal;
   3149     pu=uNormal;
   3150     ucnv_toUnicode(cnv, &pu, uNormal+LENGTHOF(uNormal), (const char **)&pc, normal+normalLength, NULL, TRUE, &errorCode);
   3151     normalLength=(int32_t)(pu-uNormal);
   3152 
   3153     pc=normal;
   3154     pu=uSwapped;
   3155     ucnv_toUnicode(swapCnv, &pu, uSwapped+LENGTHOF(uSwapped), (const char **)&pc, normal+swappedLength, NULL, TRUE, &errorCode);
   3156     swappedLength=(int32_t)(pu-uSwapped);
   3157 
   3158     if(U_FAILURE(errorCode)) {
   3159         log_err("TestEBCDICSwapLFNL error converting from %s - (%s)\n", name, u_errorName(errorCode));
   3160         goto cleanup;
   3161     }
   3162 
   3163     /* compare EBCDIC output */
   3164     if(normalLength!=swappedLength) {
   3165         log_err("TestEBCDICSwapLFNL error converting from %s - output lengths %d vs. %d\n", name, normalLength, swappedLength);
   3166         goto cleanup;
   3167     }
   3168     for(i=0; i<normalLength; ++i) {
   3169         /* swap EBCDIC LF/NL for comparison */
   3170         u=uNormal[i];
   3171         if(swap) {
   3172             if(u==0xa) {
   3173                 u=0x85;
   3174             } else if(u==0x85) {
   3175                 u=0xa;
   3176             }
   3177         }
   3178 
   3179         if(u!=uSwapped[i]) {
   3180             log_err("TestEBCDICSwapLFNL error converting from %s - did not swap properly, output[%d]=U+%04x\n", name, i, uSwapped[i]);
   3181             goto cleanup;
   3182         }
   3183     }
   3184 
   3185     /* clean up */
   3186 cleanup:
   3187     ucnv_close(cnv);
   3188     ucnv_close(swapCnv);
   3189 }
   3190 
   3191 static void
   3192 TestEBCDICSwapLFNL() {
   3193     static const struct {
   3194         const char *name;
   3195         UBool swap;
   3196     } tests[]={
   3197         { "ibm-37", TRUE },
   3198         { "ibm-1047", TRUE },
   3199         { "ibm-1140", TRUE },
   3200         { "ibm-930", TRUE },
   3201         { "iso-8859-3", FALSE }
   3202     };
   3203 
   3204     int i;
   3205 
   3206     for(i=0; i<LENGTHOF(tests); ++i) {
   3207         testSwap(tests[i].name, tests[i].swap);
   3208     }
   3209 }
   3210 #else
   3211 static void
   3212 TestEBCDICSwapLFNL() {
   3213   /* test nothing... */
   3214 }
   3215 #endif
   3216 
   3217 static const UVersionInfo ICU_34 = {3,4,0,0};
   3218 
   3219 static void TestFromUCountPending(){
   3220 #if !UCONFIG_NO_LEGACY_CONVERSION
   3221     UErrorCode status = U_ZERO_ERROR;
   3222 /*       const UChar expectedUnicode[] = { 0x20ac, 0x0005, 0x0006, 0x000b, 0xdbc4, 0xde34, 0xd84d, 0xdc56, 0xfffd}; */
   3223     static const struct {
   3224         UChar input[6];
   3225         int32_t len;
   3226         int32_t exp;
   3227     }fromUnicodeTests[] = {
   3228         /*m:n conversion*/
   3229         {{0xdbc4},1,1},
   3230         {{ 0xdbc4, 0xde34, 0xd84d},3,1},
   3231         {{ 0xdbc4, 0xde34, 0xd900},3,3},
   3232     };
   3233     int i;
   3234     UConverter* cnv = ucnv_openPackage(loadTestData(&status), "test3", &status);
   3235     if(U_FAILURE(status)){
   3236         log_data_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
   3237         return;
   3238     }
   3239     for(i=0; i<LENGTHOF(fromUnicodeTests); ++i) {
   3240         char tgt[10];
   3241         char* target = tgt;
   3242         char* targetLimit = target + 10;
   3243         const UChar* source = fromUnicodeTests[i].input;
   3244         const UChar* sourceLimit = source + fromUnicodeTests[i].len;
   3245         int32_t len = 0;
   3246         ucnv_reset(cnv);
   3247         ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3248         len = ucnv_fromUCountPending(cnv, &status);
   3249         if(U_FAILURE(status)){
   3250             log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3251             status = U_ZERO_ERROR;
   3252             continue;
   3253         }
   3254         if(len != fromUnicodeTests[i].exp){
   3255             log_err("Did not get the expeced output for ucnv_fromUInputConsumed.\n");
   3256         }
   3257     }
   3258     status = U_ZERO_ERROR;
   3259     {
   3260         /*
   3261          * The converter has to read the tail before it knows that
   3262          * only head alone matches.
   3263          * At the end, the output for head will overflow the target,
   3264          * middle will be pending, and tail will not have been consumed.
   3265          */
   3266         /*
   3267         \U00101234  -> x (<U101234>   \x07 |0)
   3268         \U00101234\U00050005 -> y (<U101234>+<U50005>          \x07+\x00+\x01\x02\x0e+\x05 |0)
   3269         \U00101234\U00050005\U00060006 -> z (<U101234>+<U50005>+<U60006> \x07+\x00+\x01\x02\x0f+\x09 |0)
   3270         \U00060007 -> unassigned
   3271         */
   3272         static const UChar head[] = {0xDBC4,0xDE34,0xD900,0xDC05,0x0000};/* \U00101234\U00050005 */
   3273         static const UChar middle[] = {0xD940,0x0000};     /* first half of \U00060006 or \U00060007 */
   3274         static const UChar tail[] = {0xDC07,0x0000};/* second half of \U00060007 */
   3275         char tgt[10];
   3276         char* target = tgt;
   3277         char* targetLimit = target + 2; /* expect overflow from converting \U00101234\U00050005 */
   3278         const UChar* source = head;
   3279         const UChar* sourceLimit = source + u_strlen(head);
   3280         int32_t len = 0;
   3281         ucnv_reset(cnv);
   3282         ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3283         len = ucnv_fromUCountPending(cnv, &status);
   3284         if(U_FAILURE(status)){
   3285             log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3286             status = U_ZERO_ERROR;
   3287         }
   3288         if(len!=4){
   3289             log_err("ucnv_fromUInputHeld did not return correct length for head\n");
   3290         }
   3291         source = middle;
   3292         sourceLimit = source + u_strlen(middle);
   3293         ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3294         len = ucnv_fromUCountPending(cnv, &status);
   3295         if(U_FAILURE(status)){
   3296             log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3297             status = U_ZERO_ERROR;
   3298         }
   3299         if(len!=5){
   3300             log_err("ucnv_fromUInputHeld did not return correct length for middle\n");
   3301         }
   3302         source = tail;
   3303         sourceLimit = source + u_strlen(tail);
   3304         ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3305         if(status != U_BUFFER_OVERFLOW_ERROR){
   3306             log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3307         }
   3308         status = U_ZERO_ERROR;
   3309         len = ucnv_fromUCountPending(cnv, &status);
   3310         /* middle[1] is pending, tail has not been consumed */
   3311         if(U_FAILURE(status)){
   3312             log_err("ucnv_fromUInputHeld call did not succeed. Error: %s\n", u_errorName(status));
   3313         }
   3314         if(len!=1){
   3315             log_err("ucnv_fromUInputHeld did not return correct length for tail\n");
   3316         }
   3317     }
   3318     ucnv_close(cnv);
   3319 #endif
   3320 }
   3321 
   3322 static void
   3323 TestToUCountPending(){
   3324 #if !UCONFIG_NO_LEGACY_CONVERSION
   3325     UErrorCode status = U_ZERO_ERROR;
   3326     static const struct {
   3327         char input[6];
   3328         int32_t len;
   3329         int32_t exp;
   3330     }toUnicodeTests[] = {
   3331         /*m:n conversion*/
   3332         {{0x05, 0x01, 0x02},3,3},
   3333         {{0x01, 0x02},2,2},
   3334         {{0x07,  0x00, 0x01, 0x02},4,4},
   3335     };
   3336 
   3337     int i;
   3338     UConverterToUCallback *oldToUAction= NULL;
   3339     UConverter* cnv = ucnv_openPackage(loadTestData(&status), "test3", &status);
   3340     if(U_FAILURE(status)){
   3341         log_data_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
   3342         return;
   3343     }
   3344     ucnv_setToUCallBack(cnv, UCNV_TO_U_CALLBACK_STOP, NULL, oldToUAction, NULL, &status);
   3345     for(i=0; i<LENGTHOF(toUnicodeTests); ++i) {
   3346         UChar tgt[10];
   3347         UChar* target = tgt;
   3348         UChar* targetLimit = target + 20;
   3349         const char* source = toUnicodeTests[i].input;
   3350         const char* sourceLimit = source + toUnicodeTests[i].len;
   3351         int32_t len = 0;
   3352         ucnv_reset(cnv);
   3353         ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3354         len = ucnv_toUCountPending(cnv,&status);
   3355         if(U_FAILURE(status)){
   3356             log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3357             status = U_ZERO_ERROR;
   3358             continue;
   3359         }
   3360         if(len != toUnicodeTests[i].exp){
   3361             log_err("Did not get the expeced output for ucnv_toUInputConsumed.\n");
   3362         }
   3363     }
   3364     status = U_ZERO_ERROR;
   3365     ucnv_close(cnv);
   3366 
   3367     {
   3368         /*
   3369          * The converter has to read the tail before it knows that
   3370          * only head alone matches.
   3371          * At the end, the output for head will overflow the target,
   3372          * mid will be pending, and tail will not have been consumed.
   3373          */
   3374         char head[] = { 0x01, 0x02, 0x03, 0x0a , 0x00};
   3375         char mid[] = { 0x01, 0x02, 0x03, 0x0b, 0x00 };
   3376         char tail[] = {  0x01, 0x02, 0x03, 0x0d, 0x00 };
   3377         /*
   3378         0x01, 0x02, 0x03, 0x0a  -> x (<U23456>    \x01\x02\x03\x0a |0)
   3379         0x01, 0x02, 0x03, 0x0b  -> y (<U000b>     \x01\x02\x03\x0b |0)
   3380         0x01, 0x02, 0x03, 0x0d  -> z (<U34567>    \x01\x02\x03\x0d |3)
   3381         0x01, 0x02, 0x03, 0x0a + 0x01, 0x02, 0x03, 0x0b + 0x01 + many more -> z (see test4 "many bytes, and bytes per UChar")
   3382         */
   3383         UChar tgt[10];
   3384         UChar* target = tgt;
   3385         UChar* targetLimit = target + 1; /* expect overflow from converting */
   3386         const char* source = head;
   3387         const char* sourceLimit = source + strlen(head);
   3388         int32_t len = 0;
   3389         cnv = ucnv_openPackage(loadTestData(&status), "test4", &status);
   3390         if(U_FAILURE(status)){
   3391             log_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
   3392             return;
   3393         }
   3394         ucnv_setToUCallBack(cnv, UCNV_TO_U_CALLBACK_STOP, NULL, oldToUAction, NULL, &status);
   3395         ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3396         len = ucnv_toUCountPending(cnv,&status);
   3397         if(U_FAILURE(status)){
   3398             log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3399         }
   3400         if(len != 4){
   3401             log_err("Did not get the expected len for head.\n");
   3402         }
   3403         source=mid;
   3404         sourceLimit = source+strlen(mid);
   3405         ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3406         len = ucnv_toUCountPending(cnv,&status);
   3407         if(U_FAILURE(status)){
   3408             log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3409         }
   3410         if(len != 8){
   3411             log_err("Did not get the expected len for mid.\n");
   3412         }
   3413 
   3414         source=tail;
   3415         sourceLimit = source+strlen(tail);
   3416         targetLimit = target;
   3417         ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
   3418         if(status != U_BUFFER_OVERFLOW_ERROR){
   3419             log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
   3420         }
   3421         status = U_ZERO_ERROR;
   3422         len = ucnv_toUCountPending(cnv,&status);
   3423         /* mid[4] is pending, tail has not been consumed */
   3424         if(U_FAILURE(status)){
   3425             log_err("ucnv_toUCountPending call did not succeed. Error: %s\n", u_errorName(status));
   3426         }
   3427         if(len != 4){
   3428             log_err("Did not get the expected len for tail.\n");
   3429         }
   3430         ucnv_close(cnv);
   3431     }
   3432 #endif
   3433 }
   3434 
   3435 static void TestOneDefaultNameChange(const char *name, const char *expected) {
   3436     UErrorCode status = U_ZERO_ERROR;
   3437     UConverter *cnv;
   3438     ucnv_setDefaultName(name);
   3439     if(strcmp(ucnv_getDefaultName(), expected)==0)
   3440         log_verbose("setDefaultName of %s works.\n", name);
   3441     else
   3442         log_err("setDefaultName of %s failed\n", name);
   3443     cnv=ucnv_open(NULL, &status);
   3444     if (U_FAILURE(status) || cnv == NULL) {
   3445         log_err("opening the default converter of %s failed\n", name);
   3446         return;
   3447     }
   3448     if(strcmp(ucnv_getName(cnv, &status), expected)==0)
   3449         log_verbose("ucnv_getName of %s works.\n", name);
   3450     else
   3451         log_err("ucnv_getName of %s failed\n", name);
   3452     ucnv_close(cnv);
   3453 }
   3454 
   3455 static void TestDefaultName(void) {
   3456     /*Testing ucnv_getDefaultName() and ucnv_setDefaultNAme()*/
   3457     static char defaultName[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
   3458     strcpy(defaultName, ucnv_getDefaultName());
   3459 
   3460     log_verbose("getDefaultName returned %s\n", defaultName);
   3461 
   3462     /*change the default name by setting it */
   3463     TestOneDefaultNameChange("UTF-8", "UTF-8");
   3464 #if U_CHARSET_IS_UTF8
   3465     TestOneDefaultNameChange("ISCII,version=1", "UTF-8");
   3466     TestOneDefaultNameChange("ISCII,version=2", "UTF-8");
   3467     TestOneDefaultNameChange("ISO-8859-1", "UTF-8");
   3468 #else
   3469 # if !UCONFIG_NO_LEGACY_CONVERSION
   3470     TestOneDefaultNameChange("ISCII,version=1", "ISCII,version=1");
   3471     TestOneDefaultNameChange("ISCII,version=2", "ISCII,version=2");
   3472 # endif
   3473     TestOneDefaultNameChange("ISO-8859-1", "ISO-8859-1");
   3474 #endif
   3475 
   3476     /*set the default name back*/
   3477     ucnv_setDefaultName(defaultName);
   3478 }
   3479 
   3480 /* Test that ucnv_compareNames() matches names according to spec. ----------- */
   3481 
   3482 static U_INLINE int
   3483 sign(int n) {
   3484     if(n==0) {
   3485         return 0;
   3486     } else if(n<0) {
   3487         return -1;
   3488     } else /* n>0 */ {
   3489         return 1;
   3490     }
   3491 }
   3492 
   3493 static void
   3494 compareNames(const char **names) {
   3495     const char *relation, *name1, *name2;
   3496     int rel, result;
   3497 
   3498     relation=*names++;
   3499     if(*relation=='=') {
   3500         rel = 0;
   3501     } else if(*relation=='<') {
   3502         rel = -1;
   3503     } else {
   3504         rel = 1;
   3505     }
   3506 
   3507     name1=*names++;
   3508     if(name1==NULL) {
   3509         return;
   3510     }
   3511     while((name2=*names++)!=NULL) {
   3512         result=ucnv_compareNames(name1, name2);
   3513         if(sign(result)!=rel) {
   3514             log_err("ucnv_compareNames(\"%s\", \"%s\")=%d, sign!=%d\n", name1, name2, result, rel);
   3515         }
   3516         name1=name2;
   3517     }
   3518 }
   3519 
   3520 static void
   3521 TestCompareNames() {
   3522     static const char *equalUTF8[]={ "=", "UTF-8", "utf_8", "u*T@f08", "Utf 8", NULL };
   3523     static const char *equalIBM[]={ "=", "ibm-37", "IBM037", "i-B-m  00037", "ibm-0037", "IBM00037", NULL };
   3524     static const char *lessMac[]={ "<", "macos-0_1-10.2", "macos-1-10.0.2", "macos-1-10.2", NULL };
   3525     static const char *lessUTF080[]={ "<", "UTF-0008", "utf$080", "u*T@f0800", "Utf 0000000009", NULL };
   3526 
   3527     compareNames(equalUTF8);
   3528     compareNames(equalIBM);
   3529     compareNames(lessMac);
   3530     compareNames(lessUTF080);
   3531 }
   3532 
   3533 static void
   3534 TestSubstString() {
   3535     static const UChar surrogate[1]={ 0xd900 };
   3536     char buffer[16];
   3537 
   3538     static const UChar sub[5]={ 0x61, 0x62, 0x63, 0x64, 0x65 };
   3539     static const char subChars[5]={ 0x61, 0x62, 0x63, 0x64, 0x65 };
   3540     UConverter *cnv;
   3541     UErrorCode errorCode;
   3542     int32_t length;
   3543     int8_t len8;
   3544 
   3545     /* UTF-16/32: test that the BOM is output before the sub character */
   3546     errorCode=U_ZERO_ERROR;
   3547     cnv=ucnv_open("UTF-16", &errorCode);
   3548     if(U_FAILURE(errorCode)) {
   3549         log_data_err("ucnv_open(UTF-16) failed - %s\n", u_errorName(errorCode));
   3550         return;
   3551     }
   3552     length=ucnv_fromUChars(cnv, buffer, (int32_t)sizeof(buffer), surrogate, 1, &errorCode);
   3553     ucnv_close(cnv);
   3554     if(U_FAILURE(errorCode) ||
   3555         length!=4 ||
   3556         NULL == ucnv_detectUnicodeSignature(buffer, length, NULL, &errorCode)
   3557     ) {
   3558         log_err("ucnv_fromUChars(UTF-16, U+D900) did not write a BOM\n");
   3559     }
   3560 
   3561     errorCode=U_ZERO_ERROR;
   3562     cnv=ucnv_open("UTF-32", &errorCode);
   3563     if(U_FAILURE(errorCode)) {
   3564         log_data_err("ucnv_open(UTF-32) failed - %s\n", u_errorName(errorCode));
   3565         return;
   3566     }
   3567     length=ucnv_fromUChars(cnv, buffer, (int32_t)sizeof(buffer), surrogate, 1, &errorCode);
   3568     ucnv_close(cnv);
   3569     if(U_FAILURE(errorCode) ||
   3570         length!=8 ||
   3571         NULL == ucnv_detectUnicodeSignature(buffer, length, NULL, &errorCode)
   3572     ) {
   3573         log_err("ucnv_fromUChars(UTF-32, U+D900) did not write a BOM\n");
   3574     }
   3575 
   3576     /* Simple API test of ucnv_setSubstString() + ucnv_getSubstChars(). */
   3577     errorCode=U_ZERO_ERROR;
   3578     cnv=ucnv_open("ISO-8859-1", &errorCode);
   3579     if(U_FAILURE(errorCode)) {
   3580         log_data_err("ucnv_open(ISO-8859-1) failed - %s\n", u_errorName(errorCode));
   3581         return;
   3582     }
   3583     ucnv_setSubstString(cnv, sub, LENGTHOF(sub), &errorCode);
   3584     if(U_FAILURE(errorCode)) {
   3585         log_err("ucnv_setSubstString(ISO-8859-1, sub[5]) failed - %s\n", u_errorName(errorCode));
   3586     } else {
   3587         len8 = sizeof(buffer);
   3588         ucnv_getSubstChars(cnv, buffer, &len8, &errorCode);
   3589         /* Stateless converter, we expect the string converted to charset bytes. */
   3590         if(U_FAILURE(errorCode) || len8!=sizeof(subChars) || 0!=uprv_memcmp(buffer, subChars, len8)) {
   3591             log_err("ucnv_getSubstChars(ucnv_setSubstString(ISO-8859-1, sub[5])) failed - %s\n", u_errorName(errorCode));
   3592         }
   3593     }
   3594     ucnv_close(cnv);
   3595 
   3596 #if !UCONFIG_NO_LEGACY_CONVERSION
   3597     errorCode=U_ZERO_ERROR;
   3598     cnv=ucnv_open("HZ", &errorCode);
   3599     if(U_FAILURE(errorCode)) {
   3600         log_data_err("ucnv_open(HZ) failed - %s\n", u_errorName(errorCode));
   3601         return;
   3602     }
   3603     ucnv_setSubstString(cnv, sub, LENGTHOF(sub), &errorCode);
   3604     if(U_FAILURE(errorCode)) {
   3605         log_err("ucnv_setSubstString(HZ, sub[5]) failed - %s\n", u_errorName(errorCode));
   3606     } else {
   3607         len8 = sizeof(buffer);
   3608         ucnv_getSubstChars(cnv, buffer, &len8, &errorCode);
   3609         /* Stateful converter, we expect that the Unicode string was set and that we get an empty char * string now. */
   3610         if(U_FAILURE(errorCode) || len8!=0) {
   3611             log_err("ucnv_getSubstChars(ucnv_setSubstString(HZ, sub[5])) failed - %s\n", u_errorName(errorCode));
   3612         }
   3613     }
   3614     ucnv_close(cnv);
   3615 #endif
   3616     /*
   3617      * Further testing of ucnv_setSubstString() is done via intltest convert.
   3618      * We do not test edge cases of illegal arguments and similar because the
   3619      * function implementation uses all of its parameters in calls to other
   3620      * functions with UErrorCode parameters.
   3621      */
   3622 }
   3623 
   3624 static void
   3625 InvalidArguments() {
   3626     UConverter *cnv;
   3627     UErrorCode errorCode;
   3628     char charBuffer[2] = {1, 1};
   3629     char ucharAsCharBuffer[2] = {2, 2};
   3630     char *charsPtr = charBuffer;
   3631     UChar *ucharsPtr = (UChar *)ucharAsCharBuffer;
   3632     UChar *ucharsBadPtr = (UChar *)(ucharAsCharBuffer + 1);
   3633 
   3634     errorCode=U_ZERO_ERROR;
   3635     cnv=ucnv_open("UTF-8", &errorCode);
   3636     if(U_FAILURE(errorCode)) {
   3637         log_err("ucnv_open() failed - %s\n", u_errorName(errorCode));
   3638         return;
   3639     }
   3640 
   3641     errorCode=U_ZERO_ERROR;
   3642     /* This one should fail because an incomplete UChar is being passed in */
   3643     ucnv_fromUnicode(cnv, &charsPtr, charsPtr, (const UChar **)&ucharsPtr, ucharsBadPtr, NULL, TRUE, &errorCode);
   3644     if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   3645         log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode));
   3646     }
   3647 
   3648     errorCode=U_ZERO_ERROR;
   3649     /* This one should fail because ucharsBadPtr is > than ucharsPtr */
   3650     ucnv_fromUnicode(cnv, &charsPtr, charsPtr, (const UChar **)&ucharsBadPtr, ucharsPtr, NULL, TRUE, &errorCode);
   3651     if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   3652         log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode));
   3653     }
   3654 
   3655     errorCode=U_ZERO_ERROR;
   3656     /* This one should fail because an incomplete UChar is being passed in */
   3657     ucnv_toUnicode(cnv, &ucharsPtr, ucharsBadPtr, (const char **)&charsPtr, charsPtr, NULL, TRUE, &errorCode);
   3658     if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   3659         log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode));
   3660     }
   3661 
   3662     errorCode=U_ZERO_ERROR;
   3663     /* This one should fail because ucharsBadPtr is > than ucharsPtr */
   3664     ucnv_toUnicode(cnv, &ucharsBadPtr, ucharsPtr, (const char **)&charsPtr, charsPtr, NULL, TRUE, &errorCode);
   3665     if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   3666         log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode));
   3667     }
   3668 
   3669     if (charBuffer[0] != 1 || charBuffer[1] != 1
   3670         || ucharAsCharBuffer[0] != 2 || ucharAsCharBuffer[1] != 2)
   3671     {
   3672         log_err("Data was incorrectly written to buffers\n");
   3673     }
   3674 
   3675     ucnv_close(cnv);
   3676 }
   3677 
   3678 static void TestGetName() {
   3679     static const char *const names[] = {
   3680         "Unicode",                  "UTF-16",
   3681         "UnicodeBigUnmarked",       "UTF-16BE",
   3682         "UnicodeBig",               "UTF-16BE,version=1",
   3683         "UnicodeLittleUnmarked",    "UTF-16LE",
   3684         "UnicodeLittle",            "UTF-16LE,version=1",
   3685         "x-UTF-16LE-BOM",           "UTF-16LE,version=1"
   3686     };
   3687     int32_t i;
   3688     for(i = 0; i < LENGTHOF(names); i += 2) {
   3689         UErrorCode errorCode = U_ZERO_ERROR;
   3690         UConverter *cnv = ucnv_open(names[i], &errorCode);
   3691         if(U_SUCCESS(errorCode)) {
   3692             const char *name = ucnv_getName(cnv, &errorCode);
   3693             if(U_FAILURE(errorCode) || 0 != strcmp(name, names[i+1])) {
   3694                 log_err("ucnv_getName(%s) = %s != %s -- %s\n",
   3695                         names[i], name, names[i+1], u_errorName(errorCode));
   3696             }
   3697             ucnv_close(cnv);
   3698         }
   3699     }
   3700 }
   3701 
   3702 static void TestUTFBOM() {
   3703     static const UChar a16[] = { 0x61 };
   3704     static const char *const names[] = {
   3705         "UTF-16",
   3706         "UTF-16,version=1",
   3707         "UTF-16BE",
   3708         "UnicodeBig",
   3709         "UTF-16LE",
   3710         "UnicodeLittle"
   3711     };
   3712     static const uint8_t expected[][5] = {
   3713 #if U_IS_BIG_ENDIAN
   3714         { 4, 0xfe, 0xff, 0, 0x61 },
   3715         { 4, 0xfe, 0xff, 0, 0x61 },
   3716 #else
   3717         { 4, 0xff, 0xfe, 0x61, 0 },
   3718         { 4, 0xff, 0xfe, 0x61, 0 },
   3719 #endif
   3720 
   3721         { 2, 0, 0x61 },
   3722         { 4, 0xfe, 0xff, 0, 0x61 },
   3723 
   3724         { 2, 0x61, 0 },
   3725         { 4, 0xff, 0xfe, 0x61, 0 }
   3726     };
   3727 
   3728     char bytes[10];
   3729     int32_t i;
   3730 
   3731     for(i = 0; i < LENGTHOF(names); ++i) {
   3732         UErrorCode errorCode = U_ZERO_ERROR;
   3733         UConverter *cnv = ucnv_open(names[i], &errorCode);
   3734         int32_t length = 0;
   3735         const uint8_t *exp = expected[i];
   3736         if (U_FAILURE(errorCode)) {
   3737            log_err_status(errorCode, "Unable to open converter: %s got error code: %s\n", names[i], u_errorName(errorCode));
   3738            continue;
   3739         }
   3740         length = ucnv_fromUChars(cnv, bytes, (int32_t)sizeof(bytes), a16, 1, &errorCode);
   3741 
   3742         if(U_FAILURE(errorCode) || length != exp[0] || 0 != memcmp(bytes, exp+1, length)) {
   3743             log_err("unexpected %s BOM writing behavior -- %s\n",
   3744                     names[i], u_errorName(errorCode));
   3745         }
   3746         ucnv_close(cnv);
   3747     }
   3748 }
   3749