void BytesTrieTest::checkNextWithState(BytesTrie &trie, const StringAndValue data[], int32_t dataLength) { BytesTrie::State noState, state; for(int32_t i=0; i<dataLength; ++i) { if((i&1)==0) { // This should have no effect. trie.resetToState(noState); } const char *expectedString=data[i].s; int32_t stringLength=strlen(expectedString); int32_t partialLength=stringLength/3; for(int32_t j=0; j<partialLength; ++j) { if(!USTRINGTRIE_MATCHES(trie.next(expectedString[j]))) { errln("trie.next()=USTRINGTRIE_NO_MATCH for a prefix of %s", data[i].s); return; } } trie.saveState(state); UStringTrieResult resultAtState=trie.current(); UStringTrieResult result; int32_t valueAtState=-99; if(USTRINGTRIE_HAS_VALUE(resultAtState)) { valueAtState=trie.getValue(); } result=trie.next(0); // mismatch if(result!=USTRINGTRIE_NO_MATCH || result!=trie.current()) { errln("trie.next(0) matched after part of %s", data[i].s); } if( resultAtState!=trie.resetToState(state).current() || (USTRINGTRIE_HAS_VALUE(resultAtState) && valueAtState!=trie.getValue()) ) { errln("trie.next(part of %s) changes current()/getValue() after " "saveState/next(0)/resetToState", data[i].s); } else if(!USTRINGTRIE_HAS_VALUE( result=trie.next(expectedString+partialLength, stringLength-partialLength)) || result!=trie.current()) { errln("trie.next(rest of %s) does not seem to contain %s after " "saveState/next(0)/resetToState", data[i].s, data[i].s); } else if(!USTRINGTRIE_HAS_VALUE( result=trie.resetToState(state). next(expectedString+partialLength, stringLength-partialLength)) || result!=trie.current()) { errln("trie does not seem to contain %s after saveState/next(rest)/resetToState", data[i].s); } else if(trie.getValue()!=data[i].value) { errln("trie value for %s is %ld=0x%lx instead of expected %ld=0x%lx", data[i].s, (long)trie.getValue(), (long)trie.getValue(), (long)data[i].value, (long)data[i].value); } trie.reset(); } }
void BytesTrieTest::checkFirst(BytesTrie &trie, const StringAndValue data[], int32_t dataLength) { for(int32_t i=0; i<dataLength; ++i) { int c=*data[i].s; if(c==0) { continue; // skip empty string } UStringTrieResult firstResult=trie.first(c); int32_t firstValue=USTRINGTRIE_HAS_VALUE(firstResult) ? trie.getValue() : -1; UStringTrieResult nextResult=trie.next(data[i].s[1]); if(firstResult!=trie.reset().next(c) || firstResult!=trie.current() || firstValue!=(USTRINGTRIE_HAS_VALUE(firstResult) ? trie.getValue() : -1) || nextResult!=trie.next(data[i].s[1]) ) { errln("trie.first(%c)!=trie.reset().next(same) for %s", c, data[i].s); } } trie.reset(); }
// next(string) is also tested in other functions, // but here we try to go partway through the string, and then beyond it. void BytesTrieTest::checkNextString(BytesTrie &trie, const StringAndValue data[], int32_t dataLength) { for(int32_t i=0; i<dataLength; ++i) { const char *expectedString=data[i].s; int32_t stringLength=strlen(expectedString); if(!trie.next(expectedString, stringLength/2)) { errln("trie.next(up to middle of string)=USTRINGTRIE_NO_MATCH for %s", data[i].s); continue; } // Test that we stop properly at the end of the string. if(trie.next(expectedString+stringLength/2, stringLength+1-stringLength/2)) { errln("trie.next(string+NUL)!=USTRINGTRIE_NO_MATCH for %s", data[i].s); } trie.reset(); } }
void BytesTrieTest::checkNext(BytesTrie &trie, const StringAndValue data[], int32_t dataLength) { BytesTrie::State state; for(int32_t i=0; i<dataLength; ++i) { int32_t stringLength= (i&1) ? -1 : strlen(data[i].s); UStringTrieResult result; if( !USTRINGTRIE_HAS_VALUE(result=trie.next(data[i].s, stringLength)) || result!=trie.current() ) { errln("trie does not seem to contain %s", data[i].s); } else if(trie.getValue()!=data[i].value) { errln("trie value for %s is %ld=0x%lx instead of expected %ld=0x%lx", data[i].s, (long)trie.getValue(), (long)trie.getValue(), (long)data[i].value, (long)data[i].value); } else if(result!=trie.current() || trie.getValue()!=data[i].value) { errln("trie value for %s changes when repeating current()/getValue()", data[i].s); } trie.reset(); stringLength=strlen(data[i].s); result=trie.current(); for(int32_t j=0; j<stringLength; ++j) { if(!USTRINGTRIE_HAS_NEXT(result)) { errln("trie.current()!=hasNext before end of %s (at index %d)", data[i].s, j); break; } if(result==USTRINGTRIE_INTERMEDIATE_VALUE) { trie.getValue(); if(trie.current()!=USTRINGTRIE_INTERMEDIATE_VALUE) { errln("trie.getValue().current()!=USTRINGTRIE_INTERMEDIATE_VALUE before end of %s (at index %d)", data[i].s, j); break; } } result=trie.next(data[i].s[j]); if(!USTRINGTRIE_MATCHES(result)) { errln("trie.next()=USTRINGTRIE_NO_MATCH before end of %s (at index %d)", data[i].s, j); break; } if(result!=trie.current()) { errln("trie.next()!=following current() before end of %s (at index %d)", data[i].s, j); break; } } if(!USTRINGTRIE_HAS_VALUE(result)) { errln("trie.next()!=hasValue at the end of %s", data[i].s); continue; } trie.getValue(); if(result!=trie.current()) { errln("trie.current() != current()+getValue()+current() after end of %s", data[i].s); } // Compare the final current() with whether next() can actually continue. trie.saveState(state); UBool nextContinues=FALSE; // Try all graphic characters; we only use those in test strings in this file. #if U_CHARSET_FAMILY==U_ASCII_FAMILY const int32_t minChar=0x20; const int32_t maxChar=0x7e; #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY const int32_t minChar=0x40; const int32_t maxChar=0xfe; #else const int32_t minChar=0; const int32_t maxChar=0xff; #endif for(int32_t c=minChar; c<=maxChar; ++c) { if(trie.resetToState(state).next(c)) { nextContinues=TRUE; break; } } if((result==USTRINGTRIE_INTERMEDIATE_VALUE)!=nextContinues) { errln("(trie.current()==USTRINGTRIE_INTERMEDIATE_VALUE) contradicts " "(trie.next(some byte)!=USTRINGTRIE_NO_MATCH) after end of %s", data[i].s); } trie.reset(); } }