os/textandloc/textandlocutils/numbergrouping/src/RegularExpression.cpp
changeset 0 bde4ae8d615e
     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