]> granicus.if.org Git - icu/commitdiff
ICU-10338 test & fix ucol_setReorderCodes({default})
authorMarkus Scherer <markus.icu@gmail.com>
Fri, 13 Sep 2013 21:21:11 +0000 (21:21 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Fri, 13 Sep 2013 21:21:11 +0000 (21:21 +0000)
X-SVN-Rev: 34319

icu4c/source/i18n/ucol.cpp
icu4c/source/i18n/ucol_res.cpp
icu4c/source/test/cintltst/cmsccoll.c

index 54fe8a3d39086e5b0820908563266e842b8c6921..c8febdf2d2d617f050ac54ec2cdfd73c27909fd6 100644 (file)
@@ -6757,12 +6757,14 @@ ucol_setReorderCodes(UCollator* coll,
         uprv_free(coll->reorderCodes);
     }
     coll->reorderCodes = NULL;
+    coll->freeReorderCodesOnClose = FALSE;
     coll->reorderCodesLength = 0;
     if (reorderCodesLength == 0) {
         if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
             uprv_free(coll->leadBytePermutationTable);
         }
         coll->leadBytePermutationTable = NULL;
+        coll->freeLeadBytePermutationTableOnClose = FALSE;
         return;
     }
     coll->reorderCodes = (int32_t*) uprv_malloc(reorderCodesLength * sizeof(int32_t));
index 9136edaa378070397dec50828a54df9243057f96..55c529eb85ff8a85f0288f54ef4614e6097373cf 100644 (file)
@@ -1049,10 +1049,13 @@ void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UE
     if (coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) {
         uprv_free(coll->reorderCodes);
     }
-    
+    coll->reorderCodes = NULL;
+    coll->freeReorderCodesOnClose = FALSE;
+
     if (coll->defaultReorderCodes != NULL && coll->freeDefaultReorderCodesOnClose == TRUE) {
         uprv_free(coll->defaultReorderCodes);
     }
+    coll->freeDefaultReorderCodesOnClose = FALSE;
     coll->defaultReorderCodesLength = parser->reorderCodesLength;
     coll->defaultReorderCodes =  (int32_t*) uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t));
     if (coll->defaultReorderCodes == NULL) {
@@ -1154,9 +1157,7 @@ U_CFUNC void U_EXPORT2
 ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
     uint16_t leadBytesSize = 256;
     uint16_t leadBytes[256];
-    int32_t internalReorderCodesLength = coll->reorderCodesLength + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST);
-    int32_t* internalReorderCodes;
-    
+
     // The lowest byte that hasn't been assigned a mapping
     int toBottom = 0x03;
     // The highest byte that hasn't been assigned a mapping - don't include the special or trailing
@@ -1184,6 +1185,7 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
                 uprv_free(coll->leadBytePermutationTable);
             }
             coll->leadBytePermutationTable = NULL;
+            coll->freeLeadBytePermutationTableOnClose = FALSE;
             coll->reorderCodesLength = 0;
         }
         return;
@@ -1199,46 +1201,50 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
             uprv_free(coll->reorderCodes);
         }
         coll->reorderCodes = NULL;
-        
+        coll->freeReorderCodesOnClose = FALSE;
+
         if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
             uprv_free(coll->leadBytePermutationTable);
         }
         coll->leadBytePermutationTable = NULL;
+        coll->freeLeadBytePermutationTableOnClose = FALSE;
 
         if (coll->defaultReorderCodesLength == 0) {
             return;
         }
         
         coll->reorderCodes = (int32_t*)uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t));
-        coll->freeReorderCodesOnClose = TRUE;
         if (coll->reorderCodes == NULL) {
             *status = U_MEMORY_ALLOCATION_ERROR;
             return;
         }
+        coll->freeReorderCodesOnClose = TRUE;
         coll->reorderCodesLength = coll->defaultReorderCodesLength;
-        uprv_memcpy(coll->defaultReorderCodes, coll->reorderCodes, coll->reorderCodesLength * sizeof(int32_t));
-    }     
+        uprv_memcpy(coll->reorderCodes, coll->defaultReorderCodes, coll->reorderCodesLength * sizeof(int32_t));
+    }
 
     if (coll->leadBytePermutationTable == NULL) {
         coll->leadBytePermutationTable = (uint8_t*)uprv_malloc(256*sizeof(uint8_t));
-        coll->freeLeadBytePermutationTableOnClose = TRUE;
         if (coll->leadBytePermutationTable == NULL) {
             *status = U_MEMORY_ALLOCATION_ERROR;
             return;
         }
+        coll->freeLeadBytePermutationTableOnClose = TRUE;
     }
 
-    // prefill the reordering codes with the leading entries
-    internalReorderCodes = (int32_t*)uprv_malloc(internalReorderCodesLength * sizeof(int32_t));
-    if (internalReorderCodes == NULL) {
+    int32_t internalReorderCodesLength = coll->reorderCodesLength + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST);
+    LocalMemory<int32_t> internalReorderCodes((int32_t*)uprv_malloc(internalReorderCodesLength * sizeof(int32_t)));
+    if (internalReorderCodes.isNull()) {
         *status = U_MEMORY_ALLOCATION_ERROR;
         if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
             uprv_free(coll->leadBytePermutationTable);
         }
         coll->leadBytePermutationTable = NULL;
+        coll->freeLeadBytePermutationTableOnClose = FALSE;
         return;
     }
-    
+
+    // prefill the reordering codes with the leading entries
     for (uint32_t codeIndex = 0; codeIndex < (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST); codeIndex++) {
         internalReorderCodes[codeIndex] = UCOL_REORDER_CODE_FIRST + codeIndex;
     }
@@ -1282,10 +1288,8 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
                     uprv_free(coll->leadBytePermutationTable);
                 }
                 coll->leadBytePermutationTable = NULL;
+                coll->freeLeadBytePermutationTableOnClose = FALSE;
                 coll->reorderCodesLength = 0;
-                if (internalReorderCodes != NULL) {
-                    uprv_free(internalReorderCodes);
-                }
                 return;
             }
             fromTheBottom = false;
@@ -1304,10 +1308,8 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
                         uprv_free(coll->leadBytePermutationTable);
                     }
                     coll->leadBytePermutationTable = NULL;
+                    coll->freeLeadBytePermutationTableOnClose = FALSE;
                     coll->reorderCodesLength = 0;
-                    if (internalReorderCodes != NULL) {
-                        uprv_free(internalReorderCodes);
-                    }
                     return;
                 }
    
@@ -1326,10 +1328,8 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
                         uprv_free(coll->leadBytePermutationTable);
                     }
                     coll->leadBytePermutationTable = NULL;
+                    coll->freeLeadBytePermutationTableOnClose = FALSE;
                     coll->reorderCodesLength = 0;
-                    if (internalReorderCodes != NULL) {
-                        uprv_free(internalReorderCodes);
-                    }
                     return;
                 }
 
@@ -1376,10 +1376,6 @@ ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
     } 
 #endif
 
-    if (internalReorderCodes != NULL) {
-        uprv_free(internalReorderCodes);
-    }
-
     // force a regen of the latin one table since it is affected by the script reordering
     coll->latinOneRegenTable = TRUE;
     ucol_updateInternalState(coll, status);
index 35b7c6a60ce6e252f3f7db88d007bb00d02d91d4..523af36a41da8caea12b8f6d1c1dcff2dec9d02a 100644 (file)
@@ -6149,14 +6149,15 @@ static void TestReorderingAPIWithRuleCreatedCollator(void)
     UErrorCode status = U_ZERO_ERROR;
     UCollator  *myCollation;
     UChar rules[90];
-    int32_t rulesReorderCodes[2] = {USCRIPT_HAN, USCRIPT_GREEK};
-    int32_t reorderCodes[3] = {USCRIPT_GREEK, USCRIPT_HAN, UCOL_REORDER_CODE_PUNCTUATION};
+    static const int32_t rulesReorderCodes[2] = {USCRIPT_HAN, USCRIPT_GREEK};
+    static const int32_t reorderCodes[3] = {USCRIPT_GREEK, USCRIPT_HAN, UCOL_REORDER_CODE_PUNCTUATION};
+    static const int32_t onlyDefault[1] = {UCOL_REORDER_CODE_DEFAULT};
     UCollationResult collResult;
     int32_t retrievedReorderCodesLength;
     int32_t retrievedReorderCodes[10];
-    UChar greekString[] = { 0x03b1 };
-    UChar punctuationString[] = { 0x203e };
-    UChar hanString[] = { 0x65E5, 0x672C };
+    static const UChar greekString[] = { 0x03b1 };
+    static const UChar punctuationString[] = { 0x203e };
+    static const UChar hanString[] = { 0x65E5, 0x672C };
     int loopIndex;
 
     log_verbose("Testing non-lead bytes in a sort key with and without reordering\n");
@@ -6187,18 +6188,17 @@ static void TestReorderingAPIWithRuleCreatedCollator(void)
     }
     collResult = ucol_strcoll(myCollation, greekString, LEN(greekString), hanString, LEN(hanString));
     if (collResult != UCOL_GREATER) {
-        log_err_status(status, "ERROR: collation result should have been UCOL_LESS\n");
+        log_err_status(status, "ERROR: collation result should have been UCOL_GREATER\n");
         return;
     }
-    
 
-    /* set the reorderding */
+    /* set the reordering */
     ucol_setReorderCodes(myCollation, reorderCodes, LEN(reorderCodes), &status);
     if (U_FAILURE(status)) {
         log_err_status(status, "ERROR: setting reorder codes: %s\n", myErrorName(status));
         return;
     }
-    
+
     /* get the reordering */
     retrievedReorderCodesLength = ucol_getReorderCodes(myCollation, NULL, 0, &status);
     if (status != U_BUFFER_OVERFLOW_ERROR) {
@@ -6231,7 +6231,7 @@ static void TestReorderingAPIWithRuleCreatedCollator(void)
         log_err_status(status, "ERROR: collation result should have been UCOL_LESS\n");
         return;
     }
-    
+
     /* clear the reordering */
     ucol_setReorderCodes(myCollation, NULL, 0, &status);    
     if (U_FAILURE(status)) {
@@ -6252,6 +6252,28 @@ static void TestReorderingAPIWithRuleCreatedCollator(void)
         return;
     }
 
+    /* reset the reordering */
+    ucol_setReorderCodes(myCollation, onlyDefault, 1, &status);
+    if (U_FAILURE(status)) {
+        log_err_status(status, "ERROR: setting reorder codes to {default}: %s\n", myErrorName(status));
+        return;
+    }
+    retrievedReorderCodesLength = ucol_getReorderCodes(myCollation, retrievedReorderCodes, LEN(retrievedReorderCodes), &status);
+    if (U_FAILURE(status)) {
+        log_err_status(status, "ERROR: getting reorder codes: %s\n", myErrorName(status));
+        return;
+    }
+    if (retrievedReorderCodesLength != LEN(rulesReorderCodes)) {
+        log_err_status(status, "ERROR: retrieved reorder codes length was %d but should have been %d\n", retrievedReorderCodesLength, LEN(rulesReorderCodes));
+        return;
+    }
+    for (loopIndex = 0; loopIndex < retrievedReorderCodesLength; loopIndex++) {
+        if (retrievedReorderCodes[loopIndex] != rulesReorderCodes[loopIndex]) {
+            log_err_status(status, "ERROR: retrieved reorder code doesn't match set reorder code at index %d\n", loopIndex);
+            return;
+        }
+    }
+
     ucol_close(myCollation);
 }