diff -r 000000000000 -r bde4ae8d615e os/textandloc/textandlocutils/numbergrouping/src/RegularExpression.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/textandloc/textandlocutils/numbergrouping/src/RegularExpression.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,279 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "RegularExpression.h" + +#define KNumOfRecognisedChars 13 + +// Panic is implemented in NumberGrouping.cpp +GLDEF_C void Panic(TNumberGroupingPanic aPanic); + +CRegularExpression::CRegularExpression() +{ +} + +CRegularExpression* CRegularExpression::NewL(RPointerArray* aPatterns) +{ + CRegularExpression* s = NewLC(aPatterns); + CleanupStack::Pop(); + return s; +} + +CRegularExpression* CRegularExpression::NewLC(RPointerArray* aPatterns) +{ + CRegularExpression* s = new(ELeave)CRegularExpression(); + CleanupStack::PushL(s); + s->ConstructL(aPatterns); + return s; +} + +void CRegularExpression::ConstructL(RPointerArray* aPatterns) +{ + GenerateStateTablesL(aPatterns); +} + +CRegularExpression::~CRegularExpression() +{ + for(TInt i = 0; i < iStateMachines.Count(); i++) + delete iStateMachines[i]; + + iStateMachines.Close(); +} + +TInt CRegularExpression::Search(const TDesC& aString) +{ + return SearchFrom(0, aString); +} + +TInt CRegularExpression::SearchFrom(TInt aIndex, const TDesC& aString) +{ + for(TInt i = aIndex; i < iStateMachines.Count(); ++i) + { + if(iStateMachines[i]->Matches(aString)) + return i; + } + + return KErrNotFound; +} + +// Do the parsing +void CRegularExpression::GenerateStateTablesL(RPointerArray* aPatterns) +{ + for(TInt nPatternCount = 0; nPatternCount < aPatterns->Count(); ++nPatternCount) + { + const TDesC& desPattern = *((*aPatterns)[nPatternCount]) ; // I know it looks horrific, but it makes the + // rest of the method _so_ much easier to read + + CStateMachine* StateMachine = CStateMachine::NewLC(KNumOfRecognisedChars, desPattern.Length()); + User::LeaveIfError(iStateMachines.Append(StateMachine)); + CleanupStack::Pop(); // now the ownership transfers to iStateMachines + + // parse the desPattern + + enum TParseState + { + EAny, + EOpenBracketFound, + EChoiceOrRange, + EChoice, + ERange, + ELookingForCloseBracket + }; + + TParseState parseState = EAny; + + TInt nPatternIndex = 0; + TInt nState = 0; + + TBuf<10> bufChoice; + bufChoice.Zero(); + + TBuf<20> bufParsingError = _L("Parsing syntax error"); + + while(nPatternIndex < desPattern.Length() ) + { + TChar cChar = desPattern[nPatternIndex]; + TBool bEndOfParse = EFalse; + + if(nPatternIndex == desPattern.Length() - 1) // end of the parse + bEndOfParse = ETrue; + + switch(cChar) + { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + switch(parseState) + { + case EAny: + iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse? + KStateMatched: + (nState + 1)); + ++nState; + break; + case EOpenBracketFound: + bufChoice.Append(cChar); + parseState = EChoiceOrRange; + break; + case EChoiceOrRange: + case EChoice: + bufChoice.Append(cChar); + parseState = EChoice; + break; + case ERange: + bufChoice.Append(cChar); + parseState = ELookingForCloseBracket; + break; + //case ELookingForCloseBracket: + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + } + break; + case '[': + switch(parseState) + { + case EAny: + bufChoice.Zero(); + parseState = EOpenBracketFound; + break; + //case EOpenBracketFound: + //case EChoiceOrRange: + //case EChoice: + //case ERange: + //case ELookingForCloseBracket: + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + + } + break; + case ']': + switch(parseState) + { + case EChoice: + { + for(TInt i = 0; i < bufChoice.Length(); ++i) + { + TChar cChar = bufChoice[i]; + + iStateMachines[nPatternCount]->AddStateTransistionL(cChar.GetNumericValue(), + nState, + bEndOfParse? + KStateMatched: + (nState + 1)); + } + + ++nState; + parseState = EAny; + } + break; + case ELookingForCloseBracket: + { + TChar cTopOfRange = bufChoice[1]; + TChar cBottomOfRange = bufChoice[0]; + + TInt nTopOfRange = cTopOfRange.GetNumericValue(); // if they're not there then something + TInt nBottomOfRange = cBottomOfRange.GetNumericValue(); // is seriously amiss... + + if(nTopOfRange < nBottomOfRange) + User::Panic(bufParsingError, KErrSyntaxError); + + for(TInt i = nBottomOfRange; i <= nTopOfRange; ++i) + { + iStateMachines[nPatternCount]->AddStateTransistionL(i, nState, bEndOfParse? + KStateMatched: + (nState + 1)); + } + ++nState; + parseState = EAny; + } + break; + //case EAny: + //case EOpenBracketFound: + //case EChoiceOrRange: + //case ERange: + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + } + break; + case '-': + switch(parseState) + { + case EChoiceOrRange: + parseState = ERange; + break; + //case EAny: + //case EOpenBracketFound: + //case ELookingForCloseBracket: + //case ERange: + //case EChoice: + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + } + break; + case '.': + case '+': + switch(parseState) + { + case EAny: + iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse? + KStateMatched: + (nState + 1)); + ++nState; + break; + //case EOpenBracketFound: + //case EChoiceOrRange: + //case ELookingForCloseBracket: + //case ERange: + //case EChoice: + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + } + break; + default: + User::Panic(bufParsingError, KErrSyntaxError); + break; + } + + ++nPatternIndex; + } + + if(parseState != EAny) + User::Panic(bufParsingError, KErrSyntaxError); + } +} + +void CRegularExpression::GetWildcardVersionOfPattern( + TInt aPatternIndex, TText aWildcard, TDes& aWildcardedPattern) const + { + __ASSERT_ALWAYS( (0 <= aPatternIndex) && (aPatternIndex < iStateMachines.Count()), + Panic(ENumberGroupingNoSuchStateMachine) ); + iStateMachines[aPatternIndex]->GetWildcardVersionOfPattern( aWildcard, aWildcardedPattern ); + } + +// End of File