ICU-2092 error status checks added

X-SVN-Rev: 13050
This commit is contained in:
Syn Wee Quek 2003-09-09 23:51:17 +00:00
parent e76f09208e
commit 6f094669a2
8 changed files with 196 additions and 58 deletions

View File

@ -80,15 +80,17 @@ BreakIterator::makeWordInstance(const Locale& key, UErrorCode& status)
else {
result = new RuleBasedBreakIterator(file, status);
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
if (result != NULL) {
delete result;
}
return NULL;
}
if (result == NULL) {
udata_close(file);
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
delete result;
result = NULL;
}
return result;
}
@ -131,14 +133,16 @@ BreakIterator::makeLineInstance(const Locale& key, UErrorCode& status)
else {
result = new RuleBasedBreakIterator(file, status);
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
if (result != NULL) {
delete result;
}
return NULL;
}
if (result == NULL) {
udata_close(file);
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
delete result;
result = NULL;
}
return result;
}
@ -169,14 +173,17 @@ BreakIterator::makeCharacterInstance(const Locale& /* key */, UErrorCode& status
// The UDataMemory is adopted by the break iterator.
result = new RuleBasedBreakIterator(file, status);
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
if (result != NULL) {
delete result;
}
return NULL;
}
if (result == NULL) {
udata_close(file);
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
delete result;
result = NULL;
}
return result;
}
@ -207,14 +214,16 @@ BreakIterator::makeSentenceInstance(const Locale& /*key */, UErrorCode& status)
// The UDataMemory is adopted by the break iterator.
result = new RuleBasedBreakIterator(file, status);
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
if (result != NULL) {
delete result;
}
return NULL;
}
if (result == NULL) {
udata_close(file);
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
delete result;
result = NULL;
}
return result;
}
@ -246,14 +255,16 @@ BreakIterator::makeTitleInstance(const Locale& /* key */, UErrorCode& status)
// The UDataMemory is adopted by the break iterator.
result = new RuleBasedBreakIterator(file, status);
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
if (result != NULL) {
delete result;
}
return NULL;
}
if (result == NULL) {
udata_close(file);
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) { // Sometimes redundant check, but simple.
delete result;
result = NULL;
}
return result;
}
@ -437,8 +448,10 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
case UBRK_SENTENCE: return BreakIterator::makeSentenceInstance(loc, status);
case UBRK_TITLE: return BreakIterator::makeTitleInstance(loc, status);
default:
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
if (U_SUCCESS(status)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
return NULL;
}
}

View File

@ -43,17 +43,18 @@ DictionaryBasedBreakIterator::DictionaryBasedBreakIterator(UDataMemory* rbbiData
init();
if (U_FAILURE(status)) {return;};
fTables = new DictionaryBasedBreakIteratorTables(dictionaryFilename, status);
if (U_FAILURE(status)) {
if (fTables != NULL) {
fTables->removeReference();
fTables = NULL;
}
return;
}
/* test for NULL */
if(fTables == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
if (U_FAILURE(status)) {
fTables->removeReference();
fTables = NULL;
return;
}
}
@ -396,6 +397,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
c = fText->next();
}
if (U_FAILURE(status)) {
return; // UStack below overwrites the status error codes
}
// initialize. We maintain two stacks: currentBreakPositions contains
// the list of break positions that will be returned if we successfully
@ -412,7 +416,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
// further, this saves us from having to follow each possible path
// through the text all the way to the error (hopefully avoiding many
// future recursive calls as well).
UStack currentBreakPositions(status);
// there can be only one kind of error in UStack and UVector, so we'll
// just let the error fall through
UStack currentBreakPositions(status);
UStack possibleBreakPositions(status);
UVector wrongBreakPositions(status);
@ -445,6 +451,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
// the possible-break-positions stack
if (fTables->fDictionary->at(state, (int32_t)0) == -1) {
possibleBreakPositions.push(fText->getIndex(), status);
if (U_FAILURE(status)) {
return;
}
}
// look up the new state to transition to in the dictionary
@ -456,6 +465,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
// of the loop.
if (state == -1) {
currentBreakPositions.push(fText->getIndex(), status);
if (U_FAILURE(status)) {
return;
}
break;
}
@ -501,6 +513,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
currentBreakPositions.removeAllElements();
for (int32_t i = 0; i < bestBreakPositions.size(); i++) {
currentBreakPositions.push(bestBreakPositions.elementAti(i), status);
if (U_FAILURE(status)) {
return;
}
}
bestBreakPositions.removeAllElements();
if (farthestEndPoint < endPos) {
@ -515,9 +530,15 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
|| currentBreakPositions.peeki() != fText->getIndex())
&& fText->getIndex() != startPos) {
currentBreakPositions.push(fText->getIndex(), status);
if (U_FAILURE(status)) {
return;
}
}
fText->next();
currentBreakPositions.push(fText->getIndex(), status);
if (U_FAILURE(status)) {
return;
}
}
}
@ -561,6 +582,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t
currentBreakPositions.popi();
}
currentBreakPositions.push(endPos, status);
if (U_FAILURE(status)) {
return;
}
// create a regular array to hold the break positions and copy
// the break positions from the stack to the array (in addition,

View File

@ -46,8 +46,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedBreakIterator)
RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status)
{
init();
fData = new RBBIDataWrapper(data, status); // status checked in constructor
if (U_FAILURE(status)) {return;}
fData = new RBBIDataWrapper(data, status);
if(fData == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
@ -63,8 +63,8 @@ RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode
RuleBasedBreakIterator::RuleBasedBreakIterator(UDataMemory* udm, UErrorCode &status)
{
init();
fData = new RBBIDataWrapper(udm, status); // status checked in constructor
if (U_FAILURE(status)) {return;}
fData = new RBBIDataWrapper(udm, status);
if(fData == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
return;

View File

@ -47,7 +47,7 @@ RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString &rules,
UErrorCode &status)
: fRules(rules)
{
fStatus = &status;
fStatus = &status; // status is checked below
fParseError = &parseErr;
fDebugEnv = NULL;
#ifdef RBBI_DEBUG
@ -59,9 +59,18 @@ RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString &rules,
fReverseTree = NULL;
fForwardTables = NULL;
fReverseTables = NULL;
fUSetNodes = new UVector(status);
UErrorCode oldstatus = status;
fUSetNodes = new UVector(status); // bcos status gets overwritten here
fScanner = new RBBIRuleScanner(this);
fSetBuilder = new RBBISetBuilder(this);
if (U_FAILURE(oldstatus)) {
status = oldstatus;
}
if (U_FAILURE(status)) {
return;
}
if(fSetBuilder == 0 || fScanner == 0 || fUSetNodes == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
}
@ -176,9 +185,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules,
UParseError &parseError,
UErrorCode &status)
{
if (U_FAILURE(status)) {
return NULL;
}
// status checked below
//
// Read the input rules, generate a parse tree, symbol table,
@ -186,7 +193,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules,
//
RBBIRuleBuilder builder(rules, parseError, status);
builder.fScanner->parse();
if (U_FAILURE(status)) {
if (U_FAILURE(status)) { // status checked here bcos build below doesn't
return NULL;
}
@ -204,7 +211,9 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules,
//
builder.fForwardTables = new RBBITableBuilder(&builder, &builder.fForwardTree);
builder.fReverseTables = new RBBITableBuilder(&builder, &builder.fReverseTree);
if(builder.fForwardTables == NULL || builder.fReverseTables == NULL) {
if (U_SUCCESS(status)
&& (builder.fForwardTables == NULL || builder.fReverseTables == NULL))
{
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
@ -220,8 +229,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules,
// Package up the compiled data into a memory image
// in the run-time format.
//
RBBIDataHeader *data;
data = builder.flattenData();
RBBIDataHeader *data = builder.flattenData(); // returns NULL if error
//
@ -233,16 +241,14 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules,
// Create a break iterator from the compiled rules.
// (Identical to creation from stored pre-compiled rules)
//
// status is checked after init in construction.
RuleBasedBreakIterator *This = new RuleBasedBreakIterator(data, status);
/* test for NULL */
if(This == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
if (U_FAILURE(status)) {
delete This;
This = NULL;
}
else if(This == NULL) { // test for NULL
status = U_MEMORY_ALLOCATION_ERROR;
}
return This;
}

View File

@ -88,6 +88,9 @@ U_NAMESPACE_BEGIN
//----------------------------------------------------------------------------------------
RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb)
{
if (U_FAILURE(*rb->fStatus)) {
return;
}
fRB = rb;
fStackPtr = 0;
fStack[fStackPtr] = 0;
@ -113,10 +116,6 @@ RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb)
fCharNum = 0;
fQuoteMode = FALSE;
if (U_FAILURE(*rb->fStatus)) {
return;
}
//
// Set up the constant Unicode Sets.
// Note: These could be made static, lazily initialized, and shared among

View File

@ -135,10 +135,13 @@ void RBBISetBuilder::build() {
// Initialize the process by creating a single range encompassing all characters
// that is in no sets.
//
fRangeList = new RangeDescriptor(*fStatus);
fRangeList = new RangeDescriptor(*fStatus); // will check for status here
fRangeList->fStartChar = 0;
fRangeList->fEndChar = 0x10ffff;
if (U_FAILURE(*fStatus)) {
return;
}
//
// Find the set of non-overlapping ranges of characters
@ -176,6 +179,9 @@ void RBBISetBuilder::build() {
// over
if (rlRange->fStartChar < inputSetRangeBegin) {
rlRange->split(inputSetRangeBegin, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
continue;
}
@ -186,12 +192,18 @@ void RBBISetBuilder::build() {
// wholly inside the Unicode set.
if (rlRange->fEndChar > inputSetRangeEnd) {
rlRange->split(inputSetRangeEnd+1, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
}
// The current rlRange is now entirely within the UnicodeSet range.
// Add this unicode set to the list of sets for this rlRange
if (rlRange->fIncludesSets->indexOf(usetNode) == -1) {
rlRange->fIncludesSets->addElement(usetNode, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
}
// Advance over ranges that we are finished with.
@ -475,7 +487,14 @@ RangeDescriptor::RangeDescriptor(const RangeDescriptor &other, UErrorCode &statu
this->fEndChar = other.fEndChar;
this->fNum = other.fNum;
this->fNext = NULL;
UErrorCode oldstatus = status;
this->fIncludesSets = new UVector(status);
if (U_FAILURE(oldstatus)) {
status = oldstatus;
}
if (U_FAILURE(status)) {
return;
}
/* test for NULL */
if (this->fIncludesSets == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
@ -498,7 +517,14 @@ RangeDescriptor::RangeDescriptor(UErrorCode &status) {
this->fEndChar = 0;
this->fNum = 0;
this->fNext = NULL;
UErrorCode oldstatus = status;
this->fIncludesSets = new UVector(status);
if (U_FAILURE(oldstatus)) {
status = oldstatus;
}
if (U_FAILURE(status)) {
return;
}
/* test for NULL */
if(this->fIncludesSets == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
@ -526,6 +552,9 @@ RangeDescriptor::~RangeDescriptor() {
void RangeDescriptor::split(UChar32 where, UErrorCode &status) {
U_ASSERT(where>fStartChar && where<=fEndChar);
RangeDescriptor *nr = new RangeDescriptor(*this, status);
if (U_FAILURE(status)) {
return;
}
/* test for NULL */
if(nr == 0) {
status = U_MEMORY_ALLOCATION_ERROR;

View File

@ -43,11 +43,12 @@ RBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules
{
fHashTable = NULL;
fCachedSetLookup = NULL;
fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &status);
// uhash_open checks status
if (U_FAILURE(status)) {
return;
}
fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &status);
uhash_setValueDeleter(fHashTable, RBBISymbolTableEntry_deleter);
}

View File

@ -27,7 +27,18 @@ RBBITableBuilder::RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode) :
fTree(*rootNode) {
fRB = rb;
fStatus = fRB->fStatus;
fDStates = new UVector(*fStatus);
UErrorCode status = U_ZERO_ERROR;
fDStates = new UVector(status);
if (U_FAILURE(*fStatus)) {
return;
}
if (U_FAILURE(status)) {
*fStatus = status;
return;
}
if (fDStates == NULL) {
*fStatus = U_MEMORY_ALLOCATION_ERROR;;
}
}
@ -309,19 +320,37 @@ void RBBITableBuilder::calcFollowPos(RBBINode *n) {
//
//-----------------------------------------------------------------------------
void RBBITableBuilder::buildStateTable() {
if (U_FAILURE(*fStatus)) {
return;
}
//
// Add a dummy state 0 - the stop state. Not from Aho.
int lastInputSymbol = fRB->fSetBuilder->getNumCharCategories() - 1;
RBBIStateDescriptor *failState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
failState->fPositions = new UVector(*fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
fDStates->addElement(failState, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
// initially, the only unmarked state in Dstates is firstpos(root),
// where toot is the root of the syntax tree for (r)#;
RBBIStateDescriptor *initialState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
initialState->fPositions = new UVector(*fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
setAdd(initialState->fPositions, fTree->fFirstPosSet);
fDStates->addElement(initialState, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
// while there is an unmarked state T in Dstates do begin
for (;;) {
@ -383,8 +412,14 @@ void RBBITableBuilder::buildStateTable() {
if (!UinDstates)
{
RBBIStateDescriptor *newState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
newState->fPositions = U;
fDStates->addElement(newState, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
ux = fDStates->size()-1;
}
@ -407,12 +442,22 @@ void RBBITableBuilder::buildStateTable() {
//
//-----------------------------------------------------------------------------
void RBBITableBuilder::flagAcceptingStates() {
if (U_FAILURE(*fStatus)) {
return;
}
UVector endMarkerNodes(*fStatus);
RBBINode *endMarker;
int32_t i;
int32_t n;
if (U_FAILURE(*fStatus)) {
return;
}
fTree->findNodes(&endMarkerNodes, RBBINode::endMark, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
for (i=0; i<endMarkerNodes.size(); i++) {
endMarker = (RBBINode *)endMarkerNodes.elementAt(i);
@ -444,12 +489,18 @@ void RBBITableBuilder::flagAcceptingStates() {
//
//-----------------------------------------------------------------------------
void RBBITableBuilder::flagLookAheadStates() {
if (U_FAILURE(*fStatus)) {
return;
}
UVector lookAheadNodes(*fStatus);
RBBINode *lookAheadNode;
int32_t i;
int32_t n;
fTree->findNodes(&lookAheadNodes, RBBINode::lookAhead, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
for (i=0; i<lookAheadNodes.size(); i++) {
lookAheadNode = (RBBINode *)lookAheadNodes.elementAt(i);
@ -471,12 +522,21 @@ void RBBITableBuilder::flagLookAheadStates() {
//
//-----------------------------------------------------------------------------
void RBBITableBuilder::flagTaggedStates() {
if (U_FAILURE(*fStatus)) {
return;
}
UVector tagNodes(*fStatus);
RBBINode *tagNode;
int32_t i;
int32_t n;
if (U_FAILURE(*fStatus)) {
return;
}
fTree->findNodes(&tagNodes, RBBINode::tag, *fStatus);
if (U_FAILURE(*fStatus)) {
return;
}
for (i=0; i<tagNodes.size(); i++) { // For each tag node t (all of 'em)
tagNode = (RBBINode *)tagNodes.elementAt(i);
@ -507,7 +567,7 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) {
int sourceSize = source->size();
int32_t si, di;
for (si=0; si<sourceSize; si++) {
for (si=0; si<sourceSize && U_SUCCESS(*fStatus); si++) {
void *elToAdd = source->elementAt(si);
for (di=0; di<destOriginalSize; di++) {
if (dest->elementAt(di) == elToAdd) {
@ -515,7 +575,7 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) {
}
}
dest->addElement(elToAdd, *fStatus);
elementAlreadyInDest: ;
elementAlreadyInDest: ;
}
}
@ -730,10 +790,16 @@ RBBIStateDescriptor::RBBIStateDescriptor(int lastInputSymbol, UErrorCode *fStatu
fTagVal = 0;
fPositions = NULL;
fDtran = NULL;
UErrorCode status = U_ZERO_ERROR;
fDtran = new UVector(lastInputSymbol+1, status);
if (U_FAILURE(*fStatus)) {
return;
}
fDtran = new UVector(lastInputSymbol+1, *fStatus);
if (U_FAILURE(status)) {
*fStatus = status;
return;
}
if (fDtran == NULL) {
*fStatus = U_MEMORY_ALLOCATION_ERROR;
return;