1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/textandlocutils/numbergrouping/src/RegularExpression.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,279 @@
1.4 +/*
1.5 +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +#include "RegularExpression.h"
1.22 +
1.23 +#define KNumOfRecognisedChars 13
1.24 +
1.25 +// Panic is implemented in NumberGrouping.cpp
1.26 +GLDEF_C void Panic(TNumberGroupingPanic aPanic);
1.27 +
1.28 +CRegularExpression::CRegularExpression()
1.29 +{
1.30 +}
1.31 +
1.32 +CRegularExpression* CRegularExpression::NewL(RPointerArray<TDesC>* aPatterns)
1.33 +{
1.34 + CRegularExpression* s = NewLC(aPatterns);
1.35 + CleanupStack::Pop();
1.36 + return s;
1.37 +}
1.38 +
1.39 +CRegularExpression* CRegularExpression::NewLC(RPointerArray<TDesC>* aPatterns)
1.40 +{
1.41 + CRegularExpression* s = new(ELeave)CRegularExpression();
1.42 + CleanupStack::PushL(s);
1.43 + s->ConstructL(aPatterns);
1.44 + return s;
1.45 +}
1.46 +
1.47 +void CRegularExpression::ConstructL(RPointerArray<TDesC>* aPatterns)
1.48 +{
1.49 + GenerateStateTablesL(aPatterns);
1.50 +}
1.51 +
1.52 +CRegularExpression::~CRegularExpression()
1.53 +{
1.54 + for(TInt i = 0; i < iStateMachines.Count(); i++)
1.55 + delete iStateMachines[i];
1.56 +
1.57 + iStateMachines.Close();
1.58 +}
1.59 +
1.60 +TInt CRegularExpression::Search(const TDesC& aString)
1.61 +{
1.62 + return SearchFrom(0, aString);
1.63 +}
1.64 +
1.65 +TInt CRegularExpression::SearchFrom(TInt aIndex, const TDesC& aString)
1.66 +{
1.67 + for(TInt i = aIndex; i < iStateMachines.Count(); ++i)
1.68 + {
1.69 + if(iStateMachines[i]->Matches(aString))
1.70 + return i;
1.71 + }
1.72 +
1.73 + return KErrNotFound;
1.74 +}
1.75 +
1.76 +// Do the parsing
1.77 +void CRegularExpression::GenerateStateTablesL(RPointerArray<TDesC>* aPatterns)
1.78 +{
1.79 + for(TInt nPatternCount = 0; nPatternCount < aPatterns->Count(); ++nPatternCount)
1.80 + {
1.81 + const TDesC& desPattern = *((*aPatterns)[nPatternCount]) ; // I know it looks horrific, but it makes the
1.82 + // rest of the method _so_ much easier to read
1.83 +
1.84 + CStateMachine* StateMachine = CStateMachine::NewLC(KNumOfRecognisedChars, desPattern.Length());
1.85 + User::LeaveIfError(iStateMachines.Append(StateMachine));
1.86 + CleanupStack::Pop(); // now the ownership transfers to iStateMachines
1.87 +
1.88 + // parse the desPattern
1.89 +
1.90 + enum TParseState
1.91 + {
1.92 + EAny,
1.93 + EOpenBracketFound,
1.94 + EChoiceOrRange,
1.95 + EChoice,
1.96 + ERange,
1.97 + ELookingForCloseBracket
1.98 + };
1.99 +
1.100 + TParseState parseState = EAny;
1.101 +
1.102 + TInt nPatternIndex = 0;
1.103 + TInt nState = 0;
1.104 +
1.105 + TBuf<10> bufChoice;
1.106 + bufChoice.Zero();
1.107 +
1.108 + TBuf<20> bufParsingError = _L("Parsing syntax error");
1.109 +
1.110 + while(nPatternIndex < desPattern.Length() )
1.111 + {
1.112 + TChar cChar = desPattern[nPatternIndex];
1.113 + TBool bEndOfParse = EFalse;
1.114 +
1.115 + if(nPatternIndex == desPattern.Length() - 1) // end of the parse
1.116 + bEndOfParse = ETrue;
1.117 +
1.118 + switch(cChar)
1.119 + {
1.120 + case '1':
1.121 + case '2':
1.122 + case '3':
1.123 + case '4':
1.124 + case '5':
1.125 + case '6':
1.126 + case '7':
1.127 + case '8':
1.128 + case '9':
1.129 + case '0':
1.130 + switch(parseState)
1.131 + {
1.132 + case EAny:
1.133 + iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
1.134 + KStateMatched:
1.135 + (nState + 1));
1.136 + ++nState;
1.137 + break;
1.138 + case EOpenBracketFound:
1.139 + bufChoice.Append(cChar);
1.140 + parseState = EChoiceOrRange;
1.141 + break;
1.142 + case EChoiceOrRange:
1.143 + case EChoice:
1.144 + bufChoice.Append(cChar);
1.145 + parseState = EChoice;
1.146 + break;
1.147 + case ERange:
1.148 + bufChoice.Append(cChar);
1.149 + parseState = ELookingForCloseBracket;
1.150 + break;
1.151 + //case ELookingForCloseBracket:
1.152 + default:
1.153 + User::Panic(bufParsingError, KErrSyntaxError);
1.154 + break;
1.155 + }
1.156 + break;
1.157 + case '[':
1.158 + switch(parseState)
1.159 + {
1.160 + case EAny:
1.161 + bufChoice.Zero();
1.162 + parseState = EOpenBracketFound;
1.163 + break;
1.164 + //case EOpenBracketFound:
1.165 + //case EChoiceOrRange:
1.166 + //case EChoice:
1.167 + //case ERange:
1.168 + //case ELookingForCloseBracket:
1.169 + default:
1.170 + User::Panic(bufParsingError, KErrSyntaxError);
1.171 + break;
1.172 +
1.173 + }
1.174 + break;
1.175 + case ']':
1.176 + switch(parseState)
1.177 + {
1.178 + case EChoice:
1.179 + {
1.180 + for(TInt i = 0; i < bufChoice.Length(); ++i)
1.181 + {
1.182 + TChar cChar = bufChoice[i];
1.183 +
1.184 + iStateMachines[nPatternCount]->AddStateTransistionL(cChar.GetNumericValue(),
1.185 + nState,
1.186 + bEndOfParse?
1.187 + KStateMatched:
1.188 + (nState + 1));
1.189 + }
1.190 +
1.191 + ++nState;
1.192 + parseState = EAny;
1.193 + }
1.194 + break;
1.195 + case ELookingForCloseBracket:
1.196 + {
1.197 + TChar cTopOfRange = bufChoice[1];
1.198 + TChar cBottomOfRange = bufChoice[0];
1.199 +
1.200 + TInt nTopOfRange = cTopOfRange.GetNumericValue(); // if they're not there then something
1.201 + TInt nBottomOfRange = cBottomOfRange.GetNumericValue(); // is seriously amiss...
1.202 +
1.203 + if(nTopOfRange < nBottomOfRange)
1.204 + User::Panic(bufParsingError, KErrSyntaxError);
1.205 +
1.206 + for(TInt i = nBottomOfRange; i <= nTopOfRange; ++i)
1.207 + {
1.208 + iStateMachines[nPatternCount]->AddStateTransistionL(i, nState, bEndOfParse?
1.209 + KStateMatched:
1.210 + (nState + 1));
1.211 + }
1.212 + ++nState;
1.213 + parseState = EAny;
1.214 + }
1.215 + break;
1.216 + //case EAny:
1.217 + //case EOpenBracketFound:
1.218 + //case EChoiceOrRange:
1.219 + //case ERange:
1.220 + default:
1.221 + User::Panic(bufParsingError, KErrSyntaxError);
1.222 + break;
1.223 + }
1.224 + break;
1.225 + case '-':
1.226 + switch(parseState)
1.227 + {
1.228 + case EChoiceOrRange:
1.229 + parseState = ERange;
1.230 + break;
1.231 + //case EAny:
1.232 + //case EOpenBracketFound:
1.233 + //case ELookingForCloseBracket:
1.234 + //case ERange:
1.235 + //case EChoice:
1.236 + default:
1.237 + User::Panic(bufParsingError, KErrSyntaxError);
1.238 + break;
1.239 + }
1.240 + break;
1.241 + case '.':
1.242 + case '+':
1.243 + switch(parseState)
1.244 + {
1.245 + case EAny:
1.246 + iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
1.247 + KStateMatched:
1.248 + (nState + 1));
1.249 + ++nState;
1.250 + break;
1.251 + //case EOpenBracketFound:
1.252 + //case EChoiceOrRange:
1.253 + //case ELookingForCloseBracket:
1.254 + //case ERange:
1.255 + //case EChoice:
1.256 + default:
1.257 + User::Panic(bufParsingError, KErrSyntaxError);
1.258 + break;
1.259 + }
1.260 + break;
1.261 + default:
1.262 + User::Panic(bufParsingError, KErrSyntaxError);
1.263 + break;
1.264 + }
1.265 +
1.266 + ++nPatternIndex;
1.267 + }
1.268 +
1.269 + if(parseState != EAny)
1.270 + User::Panic(bufParsingError, KErrSyntaxError);
1.271 + }
1.272 +}
1.273 +
1.274 +void CRegularExpression::GetWildcardVersionOfPattern(
1.275 + TInt aPatternIndex, TText aWildcard, TDes& aWildcardedPattern) const
1.276 + {
1.277 + __ASSERT_ALWAYS( (0 <= aPatternIndex) && (aPatternIndex < iStateMachines.Count()),
1.278 + Panic(ENumberGroupingNoSuchStateMachine) );
1.279 + iStateMachines[aPatternIndex]->GetWildcardVersionOfPattern( aWildcard, aWildcardedPattern );
1.280 + }
1.281 +
1.282 +// End of File