virtual void run() { uint8_t sk1[1024], sk2[1024]; uint8_t *oldSk = NULL, *newSk = sk1; int32_t oldLen = 0; int32_t prev = 0; int32_t i = 0; for(i = 0; i < noLines; i++) { if(lines[i].buflen == 0) { continue; } if(skipLineBecauseOfBug(lines[i].buff, lines[i].buflen)) { continue; } int32_t resLen = coll->getSortKey(lines[i].buff, lines[i].buflen, newSk, 1024); if(oldSk != NULL) { int32_t skres = strcmp((char *)oldSk, (char *)newSk); int32_t cmpres = coll->compare(lines[prev].buff, lines[prev].buflen, lines[i].buff, lines[i].buflen); int32_t cmpres2 = coll->compare(lines[i].buff, lines[i].buflen, lines[prev].buff, lines[prev].buflen); if(cmpres != -cmpres2) { IntlTest::gTest->errln(UnicodeString("Compare result not symmetrical on line ") + (i + 1)); break; } if(cmpres != normalizeResult(skres)) { IntlTest::gTest->errln(UnicodeString("Difference between coll->compare and sortkey compare on line ") + (i + 1)); break; } int32_t res = cmpres; if(res == 0 && !isAtLeastUCA62) { // Up to UCA 6.1, the collation test files use a custom tie-breaker, // comparing the raw input strings. res = u_strcmpCodePointOrder(lines[prev].buff, lines[i].buff); // Starting with UCA 6.2, the collation test files use the standard UCA tie-breaker, // comparing the NFD versions of the input strings, // which we do via setting strength=identical. } if(res > 0) { IntlTest::gTest->errln(UnicodeString("Line is not greater or equal than previous line, for line ") + (i + 1)); break; } } oldSk = newSk; oldLen = resLen; (void)oldLen; // Suppress set but not used warning. prev = i; newSk = (newSk == sk1)?sk2:sk1; } }
void UCAConformanceTest::testConformance(const Collator *coll) { if(testFile == 0) { return; } uint32_t skipFlags = 0; if(coll->getAttribute(UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED) { skipFlags |= IS_SHIFTED; } if(coll == rbUCA) { skipFlags |= FROM_RULES; } logln("-prop:ucaconfnosortkeys=1 turns off getSortKey() in UCAConformanceTest"); UBool withSortKeys = getProperty("ucaconfnosortkeys") == NULL; int32_t line = 0; UChar b1[1024], b2[1024]; UChar *buffer = b1, *oldB = NULL; char lineB1[1024], lineB2[1024]; char *lineB = lineB1, *oldLineB = lineB2; uint8_t sk1[1024], sk2[1024]; uint8_t *oldSk = NULL, *newSk = sk1; int32_t oldLen = 0; int32_t oldBlen = 0; uint32_t first = 0; while (fgets(lineB, 1024, testFile) != NULL) { // remove trailing whitespace u_rtrim(lineB); line++; if(*lineB == 0 || lineB[0] == '#') { continue; } int32_t buflen = u_parseString(lineB, buffer, 1024, &first, &status); if(U_FAILURE(status)) { errln("Error parsing line %ld (%s): %s\n", (long)line, u_errorName(status), lineB); status = U_ZERO_ERROR; } buffer[buflen] = 0; if(skipLineBecauseOfBug(buffer, buflen, skipFlags)) { logln("Skipping line %i because of a known bug", line); continue; } int32_t resLen = withSortKeys ? coll->getSortKey(buffer, buflen, newSk, 1024) : 0; if(oldSk != NULL) { UBool ok=TRUE; int32_t skres = withSortKeys ? strcmp((char *)oldSk, (char *)newSk) : 0; int32_t cmpres = coll->compare(oldB, oldBlen, buffer, buflen, status); int32_t cmpres2 = coll->compare(buffer, buflen, oldB, oldBlen, status); if(cmpres != -cmpres2) { errln("Compare result not symmetrical on line %i: " "previous vs. current (%d) / current vs. previous (%d)", line, cmpres, cmpres2); ok = FALSE; } // TODO: Compare with normalization turned off if the input passes the FCD test. if(withSortKeys && cmpres != normalizeResult(skres)) { errln("Difference between coll->compare (%d) and sortkey compare (%d) on line %i", cmpres, skres, line); ok = FALSE; } int32_t res = cmpres; if(res == 0 && !isAtLeastUCA62) { // Up to UCA 6.1, the collation test files use a custom tie-breaker, // comparing the raw input strings. res = u_strcmpCodePointOrder(oldB, buffer); // Starting with UCA 6.2, the collation test files use the standard UCA tie-breaker, // comparing the NFD versions of the input strings, // which we do via setting strength=identical. } if(res > 0) { errln("Line %i is not greater or equal than previous line", line); ok = FALSE; } if(!ok) { errln(" Previous data line %s", oldLineB); errln(" Current data line %s", lineB); if(withSortKeys) { UnicodeString oldS, newS; prettify(CollationKey(oldSk, oldLen), oldS); prettify(CollationKey(newSk, resLen), newS); errln(" Previous key: "+oldS); errln(" Current key: "+newS); } } } // swap buffers oldLineB = lineB; oldB = buffer; oldSk = newSk; if(lineB == lineB1) { lineB = lineB2; buffer = b2; newSk = sk2; } else { lineB = lineB1; buffer = b1; newSk = sk1; } oldLen = resLen; oldBlen = buflen; } }