libraries/spcre/test/src/spcreconsole.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // spcreconsole.cpp
       
     2 //
       
     3 // Copyright (c) 2005 - 2006, Google Inc.
       
     4 // All rights reserved.
       
     5 //
       
     6 // Redistribution and use in source and binary forms, with or without
       
     7 // modification, are permitted provided that the following conditions are
       
     8 // met:
       
     9 //
       
    10 //     * Redistributions of source code must retain the above copyright
       
    11 // notice, this list of conditions and the following disclaimer.
       
    12 //     * Redistributions in binary form must reproduce the above
       
    13 // copyright notice, this list of conditions and the following disclaimer
       
    14 // in the documentation and/or other materials provided with the
       
    15 // distribution.
       
    16 //     * Neither the name of Google Inc. nor the names of its
       
    17 // contributors may be used to endorse or promote products derived from
       
    18 // this software without specific prior written permission.
       
    19 //
       
    20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    31 //
       
    32 // Author: Sanjay Ghemawat
       
    33 //
       
    34 // Heavily refactored for Symbian OS by Accenture.
       
    35 
       
    36 
       
    37 #include <e32base.h>
       
    38 #include <e32std.h>
       
    39 #include <e32math.h>
       
    40 #include <e32cons.h>			// Console
       
    41 #include <bacline.h>
       
    42 #include <cregex.h>
       
    43 #include <tregexarg.h>
       
    44 #include <tregexoptions.h>
       
    45 
       
    46 //  Constants
       
    47 _LIT(KTextConsoleTitle, "Console");
       
    48 _LIT(KTextFailed, " failed, leave code = %d\n");
       
    49 _LIT(KTextPressAnyKey, "[press any key]\n");
       
    50 //  Global Variables
       
    51 LOCAL_D CConsoleBase* console; // write all messages to this
       
    52 TBool verboseMode = EFalse;
       
    53 
       
    54 //  Local Functions
       
    55 
       
    56 // CHECK dies with a fatal error if condition is not true.  It is *not*
       
    57 // controlled by NDEBUG, so the check will be executed regardless of
       
    58 // compilation mode.  Therefore, it is safe to do things like:
       
    59 //    CHECK_EQ(fp->Write(x), 4)
       
    60 #define CHECK(condition)								\
       
    61 	{													\
       
    62 	if (!(condition))									\
       
    63 		{                                   			\
       
    64 		_LIT(KCondition, #condition);					\
       
    65 		console->Printf(_L("%d: Check failed: %S\n"),	\
       
    66 						__LINE__, &KCondition());		\
       
    67 		User::Leave(KErrGeneral);						\
       
    68 		}												\
       
    69 	}
       
    70 
       
    71 #define CHECK_EQ(a, b)   CHECK(a == b)
       
    72 
       
    73 static void Timing1L(TInt aNumIters)
       
    74 	{
       
    75 	console->Printf(_L("Test Timing 1, %d iterations.\n"), aNumIters);
       
    76 	
       
    77 	// Same pattern lots of times
       
    78 	_LIT8(KPattern, "ruby:\\d+");
       
    79 	_LIT8(KString,"ruby:1234");
       
    80 	CRegEx* pattern = CRegEx::NewLC(KPattern());
       
    81 
       
    82 	for (TInt j = aNumIters; j > 0; j--)
       
    83 		{
       
    84 		CHECK(pattern->FullMatchL(KString()));
       
    85 		}
       
    86 	CleanupStack::PopAndDestroy(pattern);
       
    87 	}
       
    88 
       
    89 static void Timing2L(TInt aNumIters)
       
    90 	{
       
    91 	console->Printf(_L("Test Timing 2, %d iterations.\n"), aNumIters);
       
    92 	// Same pattern lots of times
       
    93 	_LIT8(KPattern, "ruby:(\\d+)");
       
    94 	_LIT8(KString,"ruby:1234");
       
    95 	CRegEx* pattern = CRegEx::NewLC(KPattern());
       
    96 
       
    97 	TInt i;
       
    98 	for (TInt j = aNumIters; j > 0; j--)
       
    99 		{
       
   100 		CHECK(pattern->FullMatchL(KString(), &i));
       
   101 		CHECK_EQ(i, 1234);
       
   102 		}
       
   103 	CleanupStack::PopAndDestroy(pattern);
       
   104 	}
       
   105 
       
   106 static void Timing3L(TInt aNumIters)
       
   107 	{
       
   108 	console->Printf(_L("Test Timing 3, %d iterations.\n"), aNumIters);
       
   109 	_LIT8(KLine, "this is another line\n");
       
   110 	HBufC8* text = HBufC8::NewLC(KLine().Length() * aNumIters);
       
   111 	TPtr8 pText = text->Des();
       
   112 
       
   113 	for (int j = aNumIters; j > 0; j--)
       
   114 		{
       
   115 		pText.Append(KLine());
       
   116 		}
       
   117 
       
   118 	CRegEx* lineMatcher = CRegEx::NewLC(_L8(".*\n"));
       
   119 
       
   120 	TInt counter = 0;
       
   121 	while (lineMatcher->ConsumeL(pText))
       
   122 		{
       
   123 		counter++;
       
   124 		}
       
   125 	CleanupStack::PopAndDestroy(2, text);
       
   126 	CHECK_EQ(counter, aNumIters);
       
   127 	console->Printf(_L("Matched %d lines\n"), counter);
       
   128 	}
       
   129 
       
   130 
       
   131 static void RadixTestsL()
       
   132 	{
       
   133 	console->Write(_L("Testing hex\n"));
       
   134 
       
   135 	#define CHECK_HEX(type, value) 										\
       
   136 		{																\
       
   137 		type v;															\
       
   138 		CRegEx* re = CRegEx::NewLC(_L8("([0-9a-fA-F]+)[uUlL]*"));		\
       
   139 		CHECK(re->FullMatchL(_L8(#value), Hex(&v)));					\
       
   140 		CHECK_EQ(v, 0x ## value);										\
       
   141 		CleanupStack::PopAndDestroy(re);								\
       
   142 		re = NULL;														\
       
   143 		}
       
   144 
       
   145 	CHECK_HEX(TInt64,     2baddeadbeefLL);
       
   146 	CHECK_HEX(TUint8,     abU);
       
   147 	CHECK_HEX(TUint16,    2badU);
       
   148 	CHECK_HEX(TUint32,    deadbeefUL);
       
   149 	CHECK_HEX(TUint,      cafebabeU);
       
   150 	#undef CHECK_HEX
       
   151 
       
   152 	console->Write(_L("Testing octal\n"));
       
   153 
       
   154 	#define CHECK_OCTAL(type, value) 									\
       
   155 		{																\
       
   156 		type v;															\
       
   157 		CRegEx* re = CRegEx::NewLC(_L8("([0-7]+)[uUlL]*"));				\
       
   158 		CHECK(re->FullMatchL(_L8(#value), Octal(&v)));					\
       
   159 		CHECK_EQ(v, 0 ## value);										\
       
   160 		CleanupStack::PopAndDestroy(re);								\
       
   161 		re = NULL;														\
       
   162 		}
       
   163 
       
   164 	CHECK_OCTAL(TInt64,		777777777777LL);
       
   165 	CHECK_OCTAL(TUint8,		177U);
       
   166 	CHECK_OCTAL(TUint16,	177777U);
       
   167 	CHECK_OCTAL(TUint32,	3777777777UL);
       
   168 	CHECK_OCTAL(TUint,		3777777777U);
       
   169 	#undef CHECK_OCTAL
       
   170 
       
   171 	console->Write(_L("Testing decimal\n"));
       
   172 	
       
   173 	#define CHECK_DECIMAL(type, value) 									\
       
   174 		{																\
       
   175 		type v;															\
       
   176 		CRegEx* re = CRegEx::NewLC(_L8("(-?[0-9]+)[uUlL]*"));			\
       
   177 		CHECK(re->FullMatchL(_L8(#value), &v));							\
       
   178 		CHECK_EQ(v, value);												\
       
   179 		CleanupStack::PopAndDestroy(re);								\
       
   180 		re = NULL;														\
       
   181 		}	
       
   182 	
       
   183 	CHECK_DECIMAL(TInt8,	-1);
       
   184 	CHECK_DECIMAL(TUint8,	1U);
       
   185 	CHECK_DECIMAL(TInt16,	-9999);
       
   186 	CHECK_DECIMAL(TUint16,	9999U);
       
   187 	CHECK_DECIMAL(TInt32,	-123456L);
       
   188 	CHECK_DECIMAL(TUint32,	123456U);
       
   189 	CHECK_DECIMAL(TInt64,	1234567890123456789LL);
       
   190 	CHECK_DECIMAL(TInt,		-1234567890);
       
   191 	CHECK_DECIMAL(TUint,	1234567890U);
       
   192 	#undef CHECK_DECIMAL
       
   193 }
       
   194 
       
   195 static void TestReplaceL()
       
   196 	{
       
   197 	console->Write(_L("Testing ReplaceL\n"));
       
   198 
       
   199 	struct ReplaceTest
       
   200 		{
       
   201 		TBuf8<32>	iRegExp;
       
   202 		TBuf8<32>	iRewrite;
       
   203 		TBuf8<64>	iOriginal;
       
   204 		TBuf8<64>	iSingle;
       
   205 		TBuf8<64>	iGlobal;
       
   206 		TInt		iGlobalCount; // the expected return value from ReplaceAll
       
   207 		};
       
   208 	
       
   209 	static const ReplaceTest tests[] =
       
   210 	{
       
   211 		// Test 1
       
   212 		{
       
   213 		_L8("(qu|[b-df-hj-np-tv-z]*)([a-z]+)"),
       
   214 		_L8("\\2\\1ay"),
       
   215 		_L8("the quick brown fox jumps over the lazy dogs."),
       
   216 		_L8("ethay quick brown fox jumps over the lazy dogs."),
       
   217 		_L8("ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday."),
       
   218 		9
       
   219 		},
       
   220 		// Test 2
       
   221 		{
       
   222 		_L8("\\w+"),
       
   223 		_L8("\\0-NOSPAM"),
       
   224 		_L8("paul.haahr@google.com"),
       
   225 		_L8("paul-NOSPAM.haahr@google.com"),
       
   226 		_L8("paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM"),
       
   227 		4
       
   228 		},
       
   229 		// Test 3
       
   230 		{_L8("^"),
       
   231 		_L8("(START)"),
       
   232 		_L8("foo"),
       
   233 		_L8("(START)foo"),
       
   234 		_L8("(START)foo"),
       
   235 		1
       
   236 		},
       
   237 		// Test 4
       
   238 		{
       
   239 		_L8("^"),
       
   240 		_L8("(START)"),
       
   241 		_L8(""),
       
   242 		_L8("(START)"),
       
   243 		_L8("(START)"),
       
   244 		1
       
   245 		},
       
   246 		// Test 5
       
   247 		{
       
   248 		_L8("$"),
       
   249 		_L8("(END)"),
       
   250 		_L8(""),
       
   251 		_L8("(END)"),
       
   252 		_L8("(END)"),
       
   253 		1
       
   254 		},
       
   255 		// Test 6
       
   256 		{
       
   257 		_L8("b"),
       
   258 		_L8("bb"),
       
   259 		_L8("ababababab"),
       
   260 		_L8("abbabababab"),
       
   261 		_L8("abbabbabbabbabb"),
       
   262 		5
       
   263 		},
       
   264 		// Test 7
       
   265 		{
       
   266 		_L8("b"),
       
   267 		_L8("bb"),
       
   268 		_L8("bbbbbb"),
       
   269 		_L8("bbbbbbb"),
       
   270 		_L8("bbbbbbbbbbbb"),
       
   271 		6
       
   272 		},
       
   273 		// Test 8
       
   274 		{_L8("b+"),
       
   275 		_L8("bb"),
       
   276 		_L8("bbbbbb"),
       
   277 		_L8("bb"),
       
   278 		_L8("bb"),
       
   279 		1
       
   280 		},
       
   281 		// Test 9
       
   282 		{
       
   283 		_L8("b*"),
       
   284 		_L8("bb"),
       
   285 		_L8("bbbbbb"),
       
   286 		_L8("bb"),
       
   287 		_L8("bb"),
       
   288 		1
       
   289 		},
       
   290 		// Test 10
       
   291 		{
       
   292 		_L8("b*"),
       
   293 		_L8("bb"),
       
   294 		_L8("aaaaa"),
       
   295 		_L8("bbaaaaa"),
       
   296 		_L8("bbabbabbabbabbabb"),
       
   297 		6
       
   298 		},
       
   299 		// Test 11
       
   300 		{
       
   301 		_L8("b*"),
       
   302 		_L8("bb"),
       
   303 		_L8("aa\naa\n"),
       
   304 		_L8("bbaa\naa\n"),
       
   305 		_L8("bbabbabb\nbbabbabb\nbb"),
       
   306 		7
       
   307 		},
       
   308 		// Test 12
       
   309 		{
       
   310 		_L8("b*"),
       
   311 		_L8("bb"),
       
   312 		_L8("aa\raa\r"),
       
   313 		_L8("bbaa\raa\r"),
       
   314 		_L8("bbabbabb\rbbabbabb\rbb"),
       
   315 		7
       
   316 		},
       
   317 		// Test 13
       
   318 		{
       
   319 		_L8("b*"),
       
   320 		_L8("bb"),
       
   321 		_L8("aa\r\naa\r\n"),
       
   322 		_L8("bbaa\r\naa\r\n"),
       
   323 		_L8("bbabbabb\r\nbbabbabb\r\nbb"),
       
   324 		7
       
   325 		},
       
   326 #ifdef SUPPORT_UTF8
       
   327 		// Test 14
       
   328 		{	
       
   329 		_L8("b*"),
       
   330 		_L8("bb"),
       
   331 		_L8("\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8"),   // utf8
       
   332 		_L8("bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8"),
       
   333 		_L8("bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb"),
       
   334 		5
       
   335 		},
       
   336 		// Test 15
       
   337 		{
       
   338 		_L8("b*"),
       
   339 		_L8("bb"),
       
   340 		_L8("\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n"),   // utf8
       
   341 		_L8("bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n"),
       
   342 		_L8("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0""bb\nbb""\xE3\x81\xB8""bb\r\nbb"),
       
   343 		9
       
   344 		},
       
   345 #endif
       
   346 		{
       
   347 		KNullDesC8(),
       
   348 		KNullDesC8(),
       
   349 		KNullDesC8(),
       
   350 		KNullDesC8(),
       
   351 		KNullDesC8(),
       
   352 		-1
       
   353 		}
       
   354 	};
       
   355 
       
   356 #ifdef SUPPORT_UTF8
       
   357 	const TBool supportUtf8 = ETrue;
       
   358 #else
       
   359 	const TBool supportUtf8 = EFalse;
       
   360 #endif
       
   361   
       
   362 	CRegEx* re = NULL;
       
   363 	TRegExOptions options = TRegExOptions(EPcreNewlineCrLf);
       
   364 	options.SetUtf8(supportUtf8);	
       
   365 	TInt i =0;
       
   366 	for (const ReplaceTest* t = tests; t->iGlobalCount > -1; ++t)
       
   367 		{		
       
   368 		console->Printf(_L("Replace Test %d\n"), ++i);
       
   369 		re = CRegEx::NewLC(t->iRegExp, options);
       
   370 		CHECK_EQ(re->Error(), KErrNone);
       
   371 		TBuf8<64> one(t->iOriginal);
       
   372 		CHECK(re->ReplaceL(t->iRewrite, one));
       
   373 		CHECK_EQ(one, t->iSingle);
       
   374 		TBuf8<64> all(t->iOriginal);
       
   375 		const TInt replaceCount = re->GlobalReplaceL(t->iRewrite, all);
       
   376 		CHECK_EQ(all, t->iGlobal);
       
   377 		CHECK_EQ(replaceCount, t->iGlobalCount);		
       
   378 		CleanupStack::PopAndDestroy(re);
       
   379 		re = NULL;
       
   380 		}
       
   381 
       
   382 	// One final test: test \r\n replacement when we're not in CRLF mode
       
   383 	{
       
   384 	TRegExOptions options2 = TRegExOptions(EPcreNewlineCr);
       
   385 	options2.SetUtf8(supportUtf8);
       
   386 	re = CRegEx::NewLC(_L8("b*"), options2);
       
   387 	CHECK_EQ(re->Error(), KErrNone);
       
   388 	TBuf8<32> all(_L8("aa\r\naa\r\n"));
       
   389 	CHECK_EQ(re->GlobalReplaceL(_L8("bb"), all), 9);
       
   390 	CHECK_EQ(all, _L8("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
       
   391 	CleanupStack::PopAndDestroy(re);
       
   392 	re = NULL;	
       
   393 	}
       
   394 	{
       
   395 	TRegExOptions options3 = TRegExOptions(EPcreNewlineLf);
       
   396 	options3.SetUtf8(supportUtf8);
       
   397 	re = CRegEx::NewLC(_L8("b*"), options3);
       
   398 	CHECK_EQ(re->Error(), KErrNone);
       
   399 	TBuf8<32> all(_L8("aa\r\naa\r\n"));
       
   400 	CHECK_EQ(re->GlobalReplaceL(_L8("bb"), all), 9);
       
   401 	CHECK_EQ(all, _L8("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
       
   402 	CleanupStack::PopAndDestroy(re);
       
   403 	re = NULL;	
       
   404 	}
       
   405 
       
   406 	// TODO: test what happens when no PCRE_NEWLINE_* flag is set.
       
   407 	//       Alas, the answer depends on how pcre was compiled.
       
   408 }
       
   409 
       
   410 static void TestExtractL()
       
   411 	{
       
   412 	console->Write(_L("Testing ExtractL\n"));
       
   413 
       
   414 	TBuf8<32> s;	
       
   415 	CRegEx* re = NULL;
       
   416 	
       
   417 	re = CRegEx::NewLC(_L8("(.*)@([^.]*)"));
       
   418 	CHECK(re->ExtractL(_L8("\\2!\\1"), _L8("boris@kremvax.ru"), s));
       
   419 	CHECK_EQ(s, _L8("kremvax!boris"));
       
   420 	CleanupStack::PopAndDestroy(re);
       
   421 	re = NULL;
       
   422 
       
   423 	// check the RE interface as well
       
   424 	re = CRegEx::NewLC(_L8(".*"));
       
   425 	CHECK(re->ExtractL(_L8("'\\0'"), _L8("foo"), s));
       
   426 	CHECK_EQ(s, _L8("'foo'"));
       
   427 	CleanupStack::PopAndDestroy(re);
       
   428 	re = NULL;
       
   429 	
       
   430 	re = CRegEx::NewLC(_L8("bar"));
       
   431 	CHECK(!re->ExtractL(_L8("'\\0'"), _L8("baz"), s));
       
   432 	CHECK_EQ(s, _L8("'foo'"));
       
   433 	CleanupStack::PopAndDestroy(re);
       
   434 	}
       
   435 
       
   436 static void TestConsumeL()
       
   437 	{
       
   438 	console->Write(_L("Testing ConsumeL\n"));
       
   439 
       
   440 	TBuf8<3> word;
       
   441 	TBuf8<24> input(_L8("   aaa b!@#$@#$cccc"));
       
   442 
       
   443 	// matches a word, possibly proceeded by whitespace
       
   444 	CRegEx* re = CRegEx::NewLC(_L8("\\s*(\\w+)"));
       
   445 	CHECK(re->ConsumeL(input, &word));
       
   446 	CHECK_EQ(word, _L8("aaa"));
       
   447 	CHECK(re->ConsumeL(input, &word));
       
   448 	CHECK_EQ(word, _L8("b"));
       
   449 	CHECK(!re->ConsumeL(input, &word));
       
   450 	CleanupStack::PopAndDestroy(re);
       
   451 	}
       
   452 
       
   453 static void TestFindAndConsumeL()
       
   454 	{
       
   455 	console->Write(_L("Testing FindAndConsumeL\n"));
       
   456 
       
   457 	TBuf8<4> word;
       
   458 	TBuf8<24> input(_L8("   aaa b!@#$@#$cccc"));
       
   459 
       
   460 	CRegEx* re = CRegEx::NewLC(_L8("(\\w+)")); // matches a word
       
   461 	CHECK(re->FindAndConsumeL(input, &word));
       
   462 	CHECK_EQ(word, _L8("aaa"));
       
   463 	CHECK(re->FindAndConsumeL(input, &word));
       
   464 	CHECK_EQ(word, _L8("b"));
       
   465 	CHECK(re->FindAndConsumeL(input, &word));
       
   466 	CHECK_EQ(word, _L8("cccc"));
       
   467 	CHECK(!re->FindAndConsumeL(input, &word));
       
   468 	CleanupStack::PopAndDestroy(re);
       
   469 	}
       
   470 
       
   471 static void TestMatchNumberPeculiarityL()
       
   472 	{
       
   473 	console->Write(_L("Testing match-number peculiarity\n"));
       
   474 
       
   475 	TBuf8<3> word1;
       
   476 	TBuf8<3> word2;
       
   477 	TBuf8<3> word3;
       
   478 
       
   479 	CRegEx* re = CRegEx::NewLC(_L8("(foo)|(bar)|(baz)"));
       
   480 	CHECK(re->PartialMatchL(_L8("foo"), &word1, &word2, &word3));
       
   481 	CHECK_EQ(word1, _L8("foo"));
       
   482 	CHECK_EQ(word2, KNullDesC8());
       
   483 	CHECK_EQ(word3, KNullDesC8());
       
   484 	CHECK(re->PartialMatchL(_L8("bar"), &word1, &word2, &word3));
       
   485 	CHECK_EQ(word1, KNullDesC8());
       
   486 	CHECK_EQ(word2, _L8("bar"));
       
   487 	CHECK_EQ(word3, KNullDesC8());
       
   488 	CHECK(re->PartialMatchL(_L8("baz"), &word1, &word2, &word3));
       
   489 	CHECK_EQ(word1, KNullDesC8());
       
   490 	CHECK_EQ(word2, KNullDesC8());
       
   491 	CHECK_EQ(word3, _L8("baz"));
       
   492 	CHECK(!re->PartialMatchL(_L8("f"), &word1, &word2, &word3));
       
   493 
       
   494 	CleanupStack::PopAndDestroy(re);
       
   495 	re = NULL;
       
   496 
       
   497 	TBuf8<12> a;
       
   498 	re = CRegEx::NewLC(_L8("(foo)|hello"));
       
   499 	CHECK(re->FullMatchL(_L8("hello"), &a));
       
   500 	CHECK_EQ(a, KNullDesC8());
       
   501 	CleanupStack::PopAndDestroy(re);
       
   502 	}
       
   503 
       
   504 static void TestRecursionL()
       
   505 	{
       
   506 	console->Write(_L("Testing recursion\n"));
       
   507 	
       
   508 	// Get one string that passes (sometimes), one that never does.
       
   509 	TBuf8<12> good(_L8("abcdefghijk"));
       
   510 	TBuf8<12> bad(_L8("acdefghijkl"));
       
   511 
       
   512 	// According to pcretest, matching text_good against (\w+)*b
       
   513 	// requires match_limit of at least 8192, and match_recursion_limit
       
   514 	// of at least 37.
       
   515 
       
   516 	TRegExOptions optionsMatchLimit;
       
   517 	optionsMatchLimit.SetMatchLimit(8192);
       
   518 	
       
   519 	CRegEx* re = CRegEx::NewLC(_L8("(\\w+)*b"), optionsMatchLimit);
       
   520 	CHECK(re->PartialMatchL(good));
       
   521 	CHECK(re->PartialMatchL(bad) == EFalse);
       
   522 	CHECK(re->FullMatchL(good) == EFalse);
       
   523 	CHECK(re->FullMatchL(bad) == EFalse);	
       
   524 	CleanupStack::PopAndDestroy(re);
       
   525 	re = NULL;
       
   526 
       
   527 	optionsMatchLimit.SetMatchLimit(1024);
       
   528 	CRegEx* re2 = CRegEx::NewLC(_L8("(\\w+)*b"), optionsMatchLimit);
       
   529 	CHECK(re2->PartialMatchL(good) == EFalse);   // because of match_limit
       
   530 	CHECK(re2->PartialMatchL(bad) == EFalse);
       
   531 	CHECK(re2->FullMatchL(good) == EFalse);
       
   532 	CHECK(re2->FullMatchL(bad) == EFalse);
       
   533 	CleanupStack::PopAndDestroy(re2);
       
   534 	re2 = NULL;
       
   535 	
       
   536 	TRegExOptions optionsMathLimitRecursion;
       
   537 	optionsMathLimitRecursion.SetMatchLimitRecursion(50);
       
   538 	CRegEx* re3 = CRegEx::NewLC(_L8("(\\w+)*b"), optionsMathLimitRecursion);
       
   539 	CHECK(re3->PartialMatchL(good));
       
   540 	CHECK(re3->PartialMatchL(bad) == EFalse);
       
   541 	CHECK(re3->FullMatchL(good) == EFalse);
       
   542 	CHECK(re3->FullMatchL(bad) == EFalse);
       
   543 	CleanupStack::PopAndDestroy(re3);
       
   544 	re3 = NULL;
       
   545 	
       
   546 	optionsMathLimitRecursion.SetMatchLimitRecursion(10);
       
   547 	CRegEx* re4 = CRegEx::NewLC(_L8("(\\w+)*b"), optionsMathLimitRecursion);
       
   548 	CHECK(re4->PartialMatchL(good) == EFalse);
       
   549 	CHECK(re4->PartialMatchL(bad) == EFalse);
       
   550 	CHECK(re4->FullMatchL(good) == EFalse);
       
   551 	CHECK(re4->FullMatchL(bad) == EFalse);
       
   552 	CleanupStack::PopAndDestroy(re4);
       
   553 	re4 = NULL;	
       
   554 	}
       
   555 
       
   556 // A meta-quoted string, interpreted as a pattern, should always match
       
   557 // the original unquoted string.
       
   558 static void TestQuoteMetaL(const TDesC8& aUnquoted, TRegExOptions aOptions =
       
   559 		TRegExOptions())
       
   560 	{
       
   561 	HBufC8* quoted = CRegEx::QuoteMetaL(aUnquoted);
       
   562 	CleanupStack::PushL(quoted);
       
   563 
       
   564 	CRegEx* re = CRegEx::NewLC(*quoted, aOptions);
       
   565 	CHECK(re->FullMatchL(aUnquoted));
       
   566 	CleanupStack::PopAndDestroy(2, quoted); // re
       
   567 	}
       
   568 
       
   569 // A string containing meaningful regexp characters, which is then meta-
       
   570 // quoted, should not generally match a string the unquoted string does.
       
   571 static void NegativeTestQuoteMetaL(const TDesC8& aUnquoted,
       
   572 		const TDesC8& aNotMatch, TRegExOptions aOptions = TRegExOptions())
       
   573 	{
       
   574 	HBufC8* quoted = CRegEx::QuoteMetaL(aUnquoted);
       
   575 	CleanupStack::PushL(quoted);
       
   576 
       
   577 	CRegEx* re = CRegEx::NewLC(*quoted, aOptions);
       
   578 	CHECK(!re->FullMatchL(aNotMatch));
       
   579 	CleanupStack::PopAndDestroy(2, quoted); // re
       
   580 	}
       
   581 
       
   582 // Tests that quoted meta characters match their original strings,
       
   583 // and that a few things that shouldn't match indeed do not.
       
   584 static void TestQuotaMetaSimpleL()
       
   585 	{
       
   586 	TestQuoteMetaL(_L8("foo"));
       
   587 	TestQuoteMetaL(_L8("foo.bar"));
       
   588 	TestQuoteMetaL(_L8("foo\\.bar"));
       
   589 	TestQuoteMetaL(_L8("[1-9]"));
       
   590 	TestQuoteMetaL(_L8("1.5-2.0?"));
       
   591 	TestQuoteMetaL(_L8("\\d"));
       
   592 	TestQuoteMetaL(_L8("Who doesn't like ice cream?"));
       
   593 	TestQuoteMetaL(_L8("((a|b)c?d*e+[f-h]i)"));
       
   594 	TestQuoteMetaL(_L8("((?!)xxx).*yyy"));
       
   595 	TestQuoteMetaL(_L8("(["));
       
   596 	TestQuoteMetaL(_L8("foo\0bar"));
       
   597 	}
       
   598 
       
   599 static void TestQuoteMetaSimpleNegativeL()
       
   600 	{
       
   601 	NegativeTestQuoteMetaL(_L8("foo"), _L8("bar"));
       
   602 	NegativeTestQuoteMetaL(_L8("..."), _L8("bar"));
       
   603 	NegativeTestQuoteMetaL(_L8("\\."), _L8("."));
       
   604 	NegativeTestQuoteMetaL(_L8("\\."), _L8(".."));
       
   605 	NegativeTestQuoteMetaL(_L8("(a)"), _L8("a"));
       
   606 	NegativeTestQuoteMetaL(_L8("(a|b)"), _L8("a"));
       
   607 	NegativeTestQuoteMetaL(_L8("(a|b)"), _L8("(a)"));
       
   608 	NegativeTestQuoteMetaL(_L8("(a|b)"), _L8("a|b"));
       
   609 	NegativeTestQuoteMetaL(_L8("[0-9]"), _L8("0"));
       
   610 	NegativeTestQuoteMetaL(_L8("[0-9]"), _L8("0-9"));
       
   611 	NegativeTestQuoteMetaL(_L8("[0-9]"), _L8("[9]"));
       
   612 	NegativeTestQuoteMetaL(_L8("((?!)xxx)"), _L8("xxx"));
       
   613 	}
       
   614 
       
   615 static void TestQuoteMetaLatin1L()
       
   616 	{
       
   617 	TestQuoteMetaL(_L8("3\xb2 = 9"));
       
   618 	}
       
   619 
       
   620 
       
   621 static void TestQuoteMetaUtf8L()
       
   622 	{
       
   623 #ifdef SUPPORT_UTF8
       
   624 	TRegExOptions options;
       
   625 	options.SetUtf8(ETrue);
       
   626 	TestQuoteMetaL(_L8("Pl\xc3\xa1\x63ido Domingo"), options);
       
   627 	TestQuoteMetaL(_L8("xyz"), options);            // No fancy utf8
       
   628 	TestQuoteMetaL(_L8("\xc2\xb0"), options);       // 2-byte utf8 (degree symbol)
       
   629 	TestQuoteMetaL(_L8("27\xc2\xb0 degrees"), options);  // As a middle character
       
   630 	TestQuoteMetaL(_L8("\xe2\x80\xb3"), options);   // 3-byte utf8 (double prime)
       
   631 	TestQuoteMetaL(_L8("\xf0\x9d\x85\x9f"), options); // 4-byte utf8 (music note)
       
   632 	TestQuoteMetaL(_L8("27\xc2\xb0")); // Interpreted as Latin-1, but should still work
       
   633 	NegativeTestQuoteMetaL(_L8("27\xc2\xb0"),               // 2-byte utf (degree symbol)
       
   634 			_L8("27\\\xc2\\\xb0"),
       
   635 			options);
       
   636 #endif
       
   637 	}
       
   638 
       
   639 
       
   640 static void TestQuoteMetaAllL()
       
   641 	{
       
   642 	console->Write(_L("Testing QuoteMeta\n"));
       
   643 
       
   644 	TestQuotaMetaSimpleL();
       
   645 	TestQuoteMetaSimpleNegativeL();
       
   646 	TestQuoteMetaLatin1L();
       
   647 	TestQuoteMetaUtf8L();
       
   648 	}
       
   649 
       
   650 //
       
   651 // Options tests contributed by
       
   652 // Giuseppe Maxia, CTO, Stardata s.r.l.
       
   653 // July 2005
       
   654 //
       
   655 static void GetOneOptionResultL(
       
   656                 const TDesC& aOptionName,
       
   657                 const TDesC8& aRegEx,
       
   658                 const TDesC8& aString,
       
   659                 TRegExOptions& aOptions,
       
   660                 TBool aFull,
       
   661                 const TDesC8& aExpected)
       
   662 	{
       
   663 	console->Printf(_L("Testing Option <%S>\n"), &aOptionName);
       
   664 	
       
   665 	if(verboseMode)
       
   666 		{
       
   667 		TBuf<32> str;
       
   668 		str.Copy(aString);
       
   669 		TBuf<32> rx;
       
   670 		rx.Copy(aRegEx);
       
   671 		TBuf<32> expected;
       
   672 		expected.Copy(aExpected);
       
   673 
       
   674 		console->Printf(_L("/%S/ finds \"%S\" within \"%S\" \n"), &rx, &expected, &str);
       
   675 		}
       
   676 	
       
   677   TBuf8<32> captured;
       
   678   CRegEx* re = CRegEx::NewLC(aRegEx, aOptions);
       
   679   
       
   680   if (aFull)
       
   681 	  {
       
   682 	  CHECK(re->FullMatchL(aString, &captured));
       
   683 	  }    
       
   684   else
       
   685 	  {
       
   686 	  CHECK(re->PartialMatchL(aString, &captured));
       
   687 	  }   
       
   688   CHECK_EQ(captured, aExpected);
       
   689   
       
   690   CleanupStack::PopAndDestroy(re);
       
   691 }
       
   692 
       
   693 static void TestOneOptionL(
       
   694                 const TDesC& aOptionName,
       
   695                 const TDesC8& aRegEx,
       
   696                 const TDesC8& aString,
       
   697                 const TRegExOptions& aOptions,
       
   698                 TBool aFull,
       
   699                 TBool aAssertive = ETrue)
       
   700 	{
       
   701 	
       
   702 	console->Printf(_L("Testing Option <%S>\n"), &aOptionName);
       
   703 	if(verboseMode)
       
   704 		{
       
   705 		_LIT(KMatches, "matches");
       
   706 		_LIT(KNoMatch, "doesn't match");
       
   707 		TBuf<32> str;
       
   708 		str.Copy(aString);
       
   709 		TBuf<64> rx;
       
   710 		rx.Copy(aRegEx);
       
   711 		
       
   712 		console->Printf(_L("'%S' %S /%S/ \n"),
       
   713 	                  &str,
       
   714 	                  (aAssertive? &KMatches() : &KNoMatch()),
       
   715 	                  &rx);	
       
   716 		}
       
   717 
       
   718 	CRegEx* re = NULL;
       
   719 	TRAPD(err, re = CRegEx::NewLC(aRegEx, aOptions); CleanupStack::Pop());
       
   720 	
       
   721 	if(err)
       
   722 		{
       
   723 		CHECK_EQ(aAssertive, EFalse);
       
   724 		return;
       
   725 		}
       
   726 	
       
   727 	CleanupStack::PushL(re);
       
   728 	
       
   729 	if (aAssertive)
       
   730 		{
       
   731 		if (aFull)
       
   732 			{
       
   733 			CHECK(re->FullMatchL(aString));
       
   734 			}     
       
   735 		else
       
   736 			{
       
   737 			CHECK(re->PartialMatchL(aString));
       
   738 			}
       
   739 		}
       
   740 	else
       
   741 		{
       
   742 		if (aFull)
       
   743 			{
       
   744 			CHECK(!re->FullMatchL(aString));
       
   745 			}		  
       
   746 		else
       
   747 			{
       
   748 			CHECK(!re->PartialMatchL(aString));
       
   749 			}
       
   750 		}
       
   751 	CleanupStack::PopAndDestroy(re);	
       
   752 	}
       
   753 
       
   754 static void TestCaseLessL()
       
   755 	{
       
   756 	TRegExOptions options;
       
   757 	TRegExOptions options2;
       
   758 	TRegExOptions caseless;
       
   759 	caseless.SetCaseless(ETrue);
       
   760 
       
   761 	options.SetCaseless(ETrue);
       
   762 	TestOneOptionL(_L("CASELESS (class)"), _L8("HELLO"), _L8("hello"), options, EFalse);
       
   763 	TestOneOptionL(_L("CASELESS (class2)"), _L8("HELLO"), _L8("hello"), options2.SetCaseless(ETrue), EFalse);
       
   764 	TestOneOptionL(_L("CASELESS (class)"), _L8("^[A-Z]+$"), _L8("Hello"), options, EFalse);
       
   765 
       
   766 	TestOneOptionL(_L("CASELESS (function)"), _L8("HELLO"), _L8("hello"), caseless, EFalse);
       
   767 	TestOneOptionL(_L("CASELESS (function)"), _L8("^[A-Z]+$"), _L8("Hello"), caseless, EFalse);
       
   768 	options.SetCaseless(EFalse);
       
   769 	TestOneOptionL(_L("no CASELESS"), _L8("HELLO"), _L8("hello"), options, EFalse, EFalse);
       
   770 	}
       
   771 
       
   772 static void TestMultilineL()
       
   773 	{
       
   774 	TRegExOptions options;
       
   775 	TRegExOptions options2;
       
   776 	TRegExOptions multiline;
       
   777 	multiline.SetMultiline(ETrue);
       
   778 
       
   779 	TBuf8<32> str(_L8("HELLO\n" "cruel\n" "world\n"));
       
   780 
       
   781 	options.SetMultiline(ETrue);
       
   782 	TestOneOptionL(_L("MULTILINE (class)"), _L8("^cruel$"), str, options, EFalse);
       
   783 	TestOneOptionL(_L("MULTILINE (class2)"), _L8("^cruel$"), str, options2.SetMultiline(ETrue), EFalse);
       
   784 	TestOneOptionL(_L("MULTILINE (function)"), _L8("^cruel$"), str, multiline, EFalse);
       
   785 	options.SetMultiline(EFalse);
       
   786 	TestOneOptionL(_L("no MULTILINE"), _L8("^cruel$"), str, options, EFalse, EFalse);
       
   787 	}
       
   788 
       
   789 static void TestDotAllL()
       
   790 	{
       
   791 	TRegExOptions options;
       
   792 	TRegExOptions options2;
       
   793 	TRegExOptions dotAll;
       
   794 	dotAll.SetDotAll(ETrue);
       
   795 
       
   796 	TBuf8<32> str(_L8("HELLO\n" "cruel\n" "world"));
       
   797 
       
   798 	options.SetDotAll(ETrue);
       
   799 	TestOneOptionL(_L("DOTALL (class)"), _L8("HELLO.*world"),str, options, ETrue);
       
   800 	TestOneOptionL(_L("DOTALL (class2)"), _L8("HELLO.*world"),str, options2.SetDotAll(ETrue), ETrue);
       
   801 	TestOneOptionL(_L("DOTALL (function)"), _L8("HELLO.*world"),str, dotAll, ETrue);
       
   802 	options.SetDotAll(EFalse);
       
   803 	TestOneOptionL(_L("no DOTALL"), _L8("HELLO.*world"),str, options, ETrue, EFalse);
       
   804 	}
       
   805 
       
   806 static void TestDollarEndOnlyL()
       
   807 	{
       
   808 	TRegExOptions options;
       
   809 	TRegExOptions options2;
       
   810 	TRegExOptions dollarEndOnly;
       
   811 	dollarEndOnly.SetDollarEndOnly(ETrue);
       
   812 
       
   813 	TBuf8<32> str(_L8("HELLO world\n"));
       
   814 
       
   815 	TestOneOptionL(_L("no DOLLAR_ENDONLY"), _L8("world$"), str, options, EFalse);
       
   816 	options.SetDollarEndOnly(ETrue);
       
   817 	TestOneOptionL(_L("DOLLAR_ENDONLY 1"), _L8("world$"), str, options, EFalse, EFalse);
       
   818 	TestOneOptionL(_L("DOLLAR_ENDONLY 2"), _L8("world$"), str, options2.SetDollarEndOnly(ETrue), EFalse, EFalse);
       
   819 	}
       
   820 
       
   821 
       
   822 static void TestExtraL()
       
   823 	{	
       
   824 	TRegExOptions options;
       
   825 
       
   826 	TBuf8<32> str(_L8("HELLO"));
       
   827 	options.SetExtra(ETrue);
       
   828 	TestOneOptionL(_L("EXTRA 1"), _L8("\\HELL\\O"), str, options, ETrue, EFalse );
       
   829 	TestOneOptionL(_L("EXTRA 2"), _L8("\\HELL\\O"), str, TRegExOptions().SetExtra(ETrue), ETrue, EFalse );
       
   830 	options.SetExtra(EFalse);
       
   831 	TestOneOptionL(_L("no EXTRA"), _L8("\\HELL\\O"), str, options, ETrue );
       
   832 	}
       
   833 
       
   834 static void TestExtendedL()
       
   835 	{
       
   836 	TRegExOptions options;
       
   837 	TRegExOptions options2;
       
   838 	TRegExOptions extended;
       
   839 	extended.SetExtended(ETrue);
       
   840 
       
   841 	TBuf8<32> str(_L8("HELLO world"));
       
   842 
       
   843 	options.SetExtended(ETrue);
       
   844 	TestOneOptionL(_L("EXTENDED (class)"), _L8("HELLO world"), str, options, EFalse, EFalse);
       
   845 	TestOneOptionL(_L("EXTENDED (class2)"), _L8("HELLO world"), str, options2.SetExtended(ETrue), EFalse, EFalse);
       
   846 	TestOneOptionL(_L("EXTENDED (class)"), _L8("^ HE L{2} O \\s+        \\w+ $      "), str, options, EFalse);
       
   847 
       
   848 	TestOneOptionL(_L("EXTENDED (function)"), _L8("HELLO world"), str, extended, EFalse, EFalse);
       
   849 	TestOneOptionL(_L("EXTENDED (function)"), _L8("^ HE L{2} O \\s+        \\w+ $      "), str, extended, EFalse);
       
   850 
       
   851 	options.SetExtended(EFalse);
       
   852 	TestOneOptionL(_L("no EXTENDED"), _L8("HELLO world"), str, options, EFalse);
       
   853 	}
       
   854 
       
   855 static void TestNoAutoCaptureL()
       
   856 	{
       
   857 	TRegExOptions options;
       
   858 	TBuf8<32> str(_L8("HELLO world"));
       
   859 	TBuf8<5> captured;
       
   860 	console->Write(_L("Testing Option <no NO_AUTO_CAPTURE>\n"));
       
   861 	if (verboseMode)
       
   862 		{
       
   863 		console->Write(_L("parentheses capture text\n"));
       
   864 		}
       
   865 
       
   866 	CRegEx* re = CRegEx::NewLC(_L8("(world|universe)$"), options);
       
   867 	CHECK(re->ExtractL(_L8("\\1"), str , captured));
       
   868 	CHECK_EQ(captured, _L8("world"));
       
   869 	options.SetNoAutoCapture(ETrue);
       
   870 	console->Write(_L("testing Option <NO_AUTO_CAPTURE>\n"));
       
   871 
       
   872 	if (verboseMode)
       
   873 		{
       
   874 		console->Write(_L("parentheses do not capture text\n"));
       
   875 		}
       
   876 
       
   877 	re->ExtractL(_L8("\\1"),str, captured);
       
   878 	CHECK_EQ(captured, _L8("world"));
       
   879 	
       
   880 	CleanupStack::PopAndDestroy(re);
       
   881 	}
       
   882 
       
   883 static void TestUngreedyL()
       
   884 	{
       
   885 	TRegExOptions options;
       
   886 	TRegExOptions ungreedy;
       
   887 	ungreedy.SetUngreedy(ETrue);
       
   888 
       
   889 	TBuf8<32> str(_L8("HELLO, 'this' is the 'world'"));
       
   890 
       
   891 	options.SetUngreedy(ETrue);
       
   892 	GetOneOptionResultL(_L("UNGREEDY 1"), _L8("('.*')"), str, options, EFalse, _L8("'this'") );
       
   893 	GetOneOptionResultL(_L("UNGREEDY 2"), _L8("('.*')"), str, ungreedy, EFalse, _L8("'this'") );
       
   894 	GetOneOptionResultL(_L("UNGREEDY"), _L8("('.*?')"), str, options, EFalse, _L8("'this' is the 'world'") );
       
   895 
       
   896 	options.SetUngreedy(EFalse);
       
   897 	GetOneOptionResultL(_L("no UNGREEDY"), _L8("('.*')"), str, options, EFalse, _L8("'this' is the 'world'") );
       
   898 	GetOneOptionResultL(_L("no UNGREEDY"), _L8("('.*?')"), str, options, EFalse, _L8("'this'") );
       
   899 	}
       
   900 
       
   901 static void TestAllOptionsL()
       
   902 	{
       
   903 	TBuf8<32> str(_L8("HELLO\n" "cruel\n" "world"));
       
   904 	TRegExOptions options;
       
   905 	options.SetAllOptions(EPcreCaseless | EPcreDotAll);
       
   906 
       
   907 	TestOneOptionL(_L("all_options (CASELESS|DOTALL)"), _L8("^hello.*WORLD"), str , options, EFalse);
       
   908 	options.SetAllOptions(0);
       
   909 	TestOneOptionL(_L("all_options (0)"), _L8("^hello.*WORLD"), str , options, EFalse, EFalse);
       
   910 	options.SetAllOptions(EPcreMultiline | EPcreExtended);
       
   911 
       
   912 	TestOneOptionL(_L("all_options (MULTILINE|EXTENDED)"), _L8(" ^ c r u e l $ "), str, options, EFalse);
       
   913 	TestOneOptionL(_L("all_options (MULTILINE|EXTENDED) with constructor"),
       
   914 	_L8(" ^ c r u e l $ "),
       
   915 	str,
       
   916 	TRegExOptions(EPcreMultiline | EPcreExtended),
       
   917 	EFalse);
       
   918 
       
   919 	TRegExOptions multilineExtended = TRegExOptions().SetMultiline(ETrue);
       
   920 	multilineExtended.SetExtended(ETrue);
       
   921 
       
   922 	TestOneOptionL(_L("all_options (MULTILINE|EXTENDED) with concatenation"),
       
   923 	_L8(" ^ c r u e l $ "),
       
   924 	str,
       
   925 	multilineExtended, EFalse);
       
   926 
       
   927 	options.SetAllOptions(0);
       
   928 	TestOneOptionL(_L("all_options (0)"), _L8("^ c r u e l $"), str, options, EFalse, EFalse);
       
   929 	}
       
   930 
       
   931 static void TestOptionsL()
       
   932 	{
       
   933 	console->Write(_L("Testing Options\n"));
       
   934 	TestCaseLessL();
       
   935 	TestMultilineL();
       
   936 	TestDotAllL();
       
   937 	TestDollarEndOnlyL();
       
   938 	TestExtendedL();
       
   939 	TestNoAutoCaptureL();
       
   940 	TestUngreedyL();
       
   941 	TestExtraL();
       
   942 	TestAllOptionsL();
       
   943 	}
       
   944 
       
   945 
       
   946 LOCAL_C void MainL()
       
   947 	{
       
   948 	
       
   949 	_LIT(KTimingArg1, "timing1");
       
   950 	_LIT(KTimingArg2, "timing2");
       
   951 	_LIT(KTimingArg3, "timing3");
       
   952 	
       
   953 	CCommandLineArguments* args = CCommandLineArguments::NewLC();
       
   954 
       
   955 	// Treat any flag as --help
       
   956 	if(args->Count() > 1 && args->Arg(1)[0] == '-')
       
   957 		{
       
   958 		console->Printf(_L("Usage: %S [%S|%S|%S num-iters]\n"), &(args->Arg(0)), &KTimingArg1(), &KTimingArg2(), &KTimingArg3());
       
   959 		console->Write(_L("If 'timingX ###' is specified, run the given timing test\n"));
       
   960 		console->Write(_L("with the given number of iterations, rather than running\n"));
       
   961 		console->Write(_L("the default corectness test.\n"));
       
   962 		CleanupStack::PopAndDestroy(args);
       
   963 		return;		
       
   964 		}
       
   965 	if(args->Count() > 1)
       
   966 		{
       
   967 		if(args->Count() == 2)
       
   968 			{
       
   969 			console->Write(_L("timing mode needs a num-iters argument\n"));
       
   970 			CleanupStack::PopAndDestroy(args);
       
   971 			return;			
       
   972 			}
       
   973 		
       
   974 		TLex lex(args->Arg(2));
       
   975 		TInt iters;
       
   976 		TInt err = lex.Val(iters);
       
   977 		
       
   978 		if(err || iters == 0)
       
   979 			{
       
   980 			CleanupStack::PopAndDestroy(args);
       
   981 			return;	
       
   982 			}
       
   983 		
       
   984 		if(args->Arg(1) == KTimingArg1)
       
   985 			{
       
   986 			Timing1L(iters);
       
   987 			}
       
   988 		else if(args->Arg(1) == KTimingArg2)
       
   989 			{
       
   990 			Timing2L(iters);
       
   991 			}
       
   992 		else if(args->Arg(1) == KTimingArg3)
       
   993 			{
       
   994 			Timing3L(iters);
       
   995 			}		
       
   996 		else
       
   997 			{
       
   998 			console->Printf(_L("Unknown argument '%S'\n"), &(args->Arg(1)));
       
   999 			}
       
  1000 		CleanupStack::PopAndDestroy(args);
       
  1001 		return;			
       
  1002 		}
       
  1003 	CleanupStack::PopAndDestroy(args);
       
  1004 	
       
  1005 	console->Write(_L("Testing FullMatch\n"));
       
  1006 
       
  1007 	CRegEx* re = NULL;
       
  1008 	TInt i;
       
  1009 	TBuf8<10> s;
       
  1010 	
       
  1011 	/***** FullMatch with no args *****/
       
  1012 	re = CRegEx::NewLC(_L8("h.*o"));
       
  1013 	CHECK(re->FullMatchL(_L8("hello")));
       
  1014 	CleanupStack::PopAndDestroy(re);
       
  1015 	re = NULL;
       
  1016 
       
  1017 	re = CRegEx::NewLC(_L8("h.*o")); // Must be anchored at front
       
  1018 	CHECK(!re->FullMatchL(_L8("othello")));
       
  1019 	CleanupStack::PopAndDestroy(re);
       
  1020 	re = NULL;
       
  1021 
       
  1022 	re = CRegEx::NewLC(_L8("h.*o")); // Must be anchored at end
       
  1023 	CHECK(!re->FullMatchL(_L8("hello!")));
       
  1024 	CleanupStack::PopAndDestroy(re);
       
  1025 	re = NULL;
       
  1026 
       
  1027 	re = CRegEx::NewLC(_L8("a*")); // Fullmatch with normal op
       
  1028 	CHECK(re->FullMatchL(_L8("aaaa")));
       
  1029 	CleanupStack::PopAndDestroy(re);
       
  1030 	re = NULL;
       
  1031 
       
  1032 	re = CRegEx::NewLC(_L8("a*?")); // Fullmatch with nongreedy op
       
  1033 	CHECK(re->FullMatchL(_L8("aaaa")));
       
  1034 	CleanupStack::PopAndDestroy(re);
       
  1035 	re = NULL;
       
  1036 
       
  1037 	re = CRegEx::NewLC(_L8("a*?\\z")); // Two unusual ops
       
  1038 	CHECK(re->FullMatchL(_L8("aaaa")));
       
  1039 	CleanupStack::PopAndDestroy(re);
       
  1040 	re = NULL;
       
  1041 
       
  1042 	/***** FullMatch with args *****/
       
  1043 
       
  1044 	// Zero-arg
       
  1045 	re = CRegEx::NewLC(_L8("\\d+"));
       
  1046 	CHECK(re->FullMatchL(_L8("1001")));
       
  1047 	CleanupStack::PopAndDestroy(re);
       
  1048 	re = NULL;	
       
  1049 
       
  1050 	// Single-arg
       
  1051 	re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1052 	CHECK(re->FullMatchL(_L8("1001"), &i));
       
  1053 	CHECK_EQ(i, 1001);
       
  1054 	CleanupStack::PopAndDestroy(re);
       
  1055 	re = NULL;	
       
  1056 	
       
  1057 	re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1058 	CHECK(re->FullMatchL(_L8("-123"), &i));
       
  1059 	CHECK_EQ(i, -123);
       
  1060 	CleanupStack::PopAndDestroy(re);
       
  1061 	re = NULL;
       
  1062 	
       
  1063 	re = CRegEx::NewLC(_L8("()\\d+"));
       
  1064 	CHECK(!re->FullMatchL(_L8("10"), &i));
       
  1065 	CleanupStack::PopAndDestroy(re);
       
  1066 	re = NULL;
       
  1067 	
       
  1068 	re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1069 	CHECK(!re->FullMatchL(_L8("1234567890123456789012345678901234567890"), &i));
       
  1070 	CleanupStack::PopAndDestroy(re);
       
  1071 	re = NULL;	
       
  1072 
       
  1073 	// Digits surrounding integer-arg
       
  1074 	re = CRegEx::NewLC(_L8("1(\\d*)4"));
       
  1075 	CHECK(re->FullMatchL(_L8("1234"), &i));
       
  1076 	CHECK_EQ(i, 23);
       
  1077 	CleanupStack::PopAndDestroy(re);
       
  1078 	re = NULL;
       
  1079 	
       
  1080 	re = CRegEx::NewLC(_L8("(\\d)\\d+"));
       
  1081 	CHECK(re->FullMatchL(_L8("1234"), &i));
       
  1082 	CHECK_EQ(i, 1);
       
  1083 	CleanupStack::PopAndDestroy(re);
       
  1084 	re = NULL;
       
  1085 	
       
  1086 	re = CRegEx::NewLC(_L8("(-\\d)\\d+"));
       
  1087 	CHECK(re->FullMatchL(_L8("-1234"), &i));
       
  1088 	CHECK_EQ(i, -1);
       
  1089 	CleanupStack::PopAndDestroy(re);
       
  1090 	re = NULL;
       
  1091 	
       
  1092 	re = CRegEx::NewLC(_L8("(\\d)"));
       
  1093 	CHECK(re->PartialMatchL(_L8("1234"), &i));
       
  1094 	CHECK_EQ(i, 1);
       
  1095 	CleanupStack::PopAndDestroy(re);
       
  1096 	re = NULL;
       
  1097 
       
  1098 	re = CRegEx::NewLC(_L8("(-\\d)"));
       
  1099 	CHECK(re->PartialMatchL(_L8("-1234"), &i));
       
  1100 	CHECK_EQ(i, -1);
       
  1101 	CleanupStack::PopAndDestroy(re);
       
  1102 	re = NULL;
       
  1103 
       
  1104 	// String-arg
       
  1105 	re = CRegEx::NewLC(_L8("h(.*)o"));
       
  1106 	CHECK(re->PartialMatchL(_L8("hello"), &s));
       
  1107 	CHECK_EQ(s, _L8("ell"));
       
  1108 	CleanupStack::PopAndDestroy(re);
       
  1109 	re = NULL;	
       
  1110 
       
  1111 	// Multi-arg
       
  1112 	re = CRegEx::NewLC(_L8("(\\w+):(\\d+)"));
       
  1113 	CHECK(re->PartialMatchL(_L8("ruby:1234"), &s, &i));
       
  1114 	CHECK_EQ(s.Length(), 4);
       
  1115 	CHECK_EQ(s, _L8("ruby"));
       
  1116 	CHECK_EQ(i, 1234);
       
  1117 	CleanupStack::PopAndDestroy(re);
       
  1118 	re = NULL;		
       
  1119 
       
  1120 	// Ignore non-void* NULL arg
       
  1121 	re = CRegEx::NewLC(_L8("he(.*)lo"));
       
  1122 	CHECK(re->FullMatchL(_L8("hello"), (TDes8*)NULL));
       
  1123 	CleanupStack::PopAndDestroy(re);
       
  1124 	re = NULL;		
       
  1125 	
       
  1126 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1127 	CHECK(re->FullMatchL(_L8("123"), (TInt8*)NULL));
       
  1128 	CleanupStack::PopAndDestroy(re);
       
  1129 	re = NULL;			
       
  1130 
       
  1131 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1132 	CHECK(re->FullMatchL(_L8("12345"), (TInt16*)NULL));
       
  1133 	CleanupStack::PopAndDestroy(re);
       
  1134 	re = NULL;			
       
  1135 
       
  1136 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1137 	CHECK(re->FullMatchL(_L8("1234567890"), (TInt32*)NULL));
       
  1138 	CleanupStack::PopAndDestroy(re);
       
  1139 	re = NULL;			
       
  1140 
       
  1141 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1142 	CHECK(re->FullMatchL(_L8("1234567890123456"), (TInt64*)NULL));
       
  1143 	CleanupStack::PopAndDestroy(re);
       
  1144 	re = NULL;		
       
  1145 	
       
  1146 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1147 	CHECK(re->FullMatchL(_L8("1234567890"), (TInt*)NULL));
       
  1148 	CleanupStack::PopAndDestroy(re);
       
  1149 	re = NULL;		
       
  1150 	
       
  1151 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1152 	CHECK(re->FullMatchL(_L8("123"), (TUint8*)NULL));
       
  1153 	CleanupStack::PopAndDestroy(re);
       
  1154 	re = NULL;		
       
  1155 	
       
  1156 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1157 	CHECK(re->FullMatchL(_L8("12345"), (TUint16*)NULL));
       
  1158 	CleanupStack::PopAndDestroy(re);
       
  1159 	re = NULL;		
       
  1160 
       
  1161 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1162 	CHECK(re->FullMatchL(_L8("1234567890"), (TUint32*)NULL));
       
  1163 	CleanupStack::PopAndDestroy(re);
       
  1164 	re = NULL;		
       
  1165 	
       
  1166 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1167 	CHECK(re->FullMatchL(_L8("1234567890"), (TUint*)NULL));
       
  1168 	CleanupStack::PopAndDestroy(re);
       
  1169 	re = NULL;
       
  1170 	
       
  1171 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1172 	CHECK(re->FullMatchL(_L8("123.4567890123456"), (TReal32*)NULL));
       
  1173 	CleanupStack::PopAndDestroy(re);
       
  1174 	re = NULL;
       
  1175 	
       
  1176 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1177 	CHECK(re->FullMatchL(_L8("123.4567890123456"), (TReal64*)NULL));
       
  1178 	CleanupStack::PopAndDestroy(re);
       
  1179 	re = NULL;	
       
  1180 	
       
  1181 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1182 	CHECK(re->FullMatchL(_L8("123.4567890123456"), (TReal*)NULL));
       
  1183 	CleanupStack::PopAndDestroy(re);
       
  1184 	re = NULL;	
       
  1185 	
       
  1186 	// Fail on non-void* NULL arg if the match doesn't parse for the given type.
       
  1187 	re = CRegEx::NewLC(_L8("h(.*)lo"));
       
  1188 	CHECK(!re->FullMatchL(_L8("hello"), &s, (TDes8*)NULL));
       
  1189 	CleanupStack::PopAndDestroy(re);
       
  1190 	re = NULL;	
       
  1191 	
       
  1192 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1193 	CHECK(!re->FullMatchL(_L8("hello"), (TInt8*)NULL));
       
  1194 	CleanupStack::PopAndDestroy(re);
       
  1195 	re = NULL;
       
  1196 	
       
  1197 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1198 	CHECK(!re->FullMatchL(_L8("hello"), (TInt16*)NULL));
       
  1199 	CleanupStack::PopAndDestroy(re);
       
  1200 	re = NULL;	
       
  1201 	
       
  1202 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1203 	CHECK(!re->FullMatchL(_L8("hello"), (TInt32*)NULL));
       
  1204 	CleanupStack::PopAndDestroy(re);
       
  1205 	re = NULL;	
       
  1206 
       
  1207 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1208 	CHECK(!re->FullMatchL(_L8("hello"), (TInt64*)NULL));
       
  1209 	CleanupStack::PopAndDestroy(re);
       
  1210 	re = NULL;	
       
  1211 	
       
  1212 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1213 	CHECK(!re->FullMatchL(_L8("hello"), (TInt*)NULL));
       
  1214 	CleanupStack::PopAndDestroy(re);
       
  1215 	re = NULL;	
       
  1216 	
       
  1217 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1218 	CHECK(!re->FullMatchL(_L8("hello"), (TUint8*)NULL));
       
  1219 	CleanupStack::PopAndDestroy(re);
       
  1220 	re = NULL;	
       
  1221 	
       
  1222 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1223 	CHECK(!re->FullMatchL(_L8("hello"), (TUint16*)NULL));
       
  1224 	CleanupStack::PopAndDestroy(re);
       
  1225 	re = NULL;	
       
  1226 	
       
  1227 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1228 	CHECK(!re->FullMatchL(_L8("hello"), (TUint32*)NULL));
       
  1229 	CleanupStack::PopAndDestroy(re);
       
  1230 	re = NULL;	
       
  1231 	
       
  1232 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1233 	CHECK(!re->FullMatchL(_L8("hello"), (TUint*)NULL));
       
  1234 	CleanupStack::PopAndDestroy(re);
       
  1235 	re = NULL;	
       
  1236 	
       
  1237 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1238 	CHECK(!re->FullMatchL(_L8("hello"), (TReal32*)NULL));
       
  1239 	CleanupStack::PopAndDestroy(re);
       
  1240 	re = NULL;	
       
  1241 	
       
  1242 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1243 	CHECK(!re->FullMatchL(_L8("hello"), (TReal64*)NULL));
       
  1244 	CleanupStack::PopAndDestroy(re);
       
  1245 	re = NULL;	
       
  1246 	
       
  1247 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1248 	CHECK(!re->FullMatchL(_L8("hello"), (TReal*)NULL));
       
  1249 	CleanupStack::PopAndDestroy(re);
       
  1250 	re = NULL;		
       
  1251 	
       
  1252 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1253 	CHECK(!re->FullMatchL(_L8("1234"), (TInt8*)NULL));
       
  1254 	CleanupStack::PopAndDestroy(re);
       
  1255 	re = NULL;
       
  1256 	
       
  1257 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1258 	CHECK(!re->FullMatchL(_L8("123456"), (TInt16*)NULL));
       
  1259 	CleanupStack::PopAndDestroy(re);
       
  1260 	re = NULL;	
       
  1261 	
       
  1262 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1263 	CHECK(!re->FullMatchL(_L8("12345678901"), (TInt32*)NULL));
       
  1264 	CleanupStack::PopAndDestroy(re);
       
  1265 	re = NULL;	
       
  1266 	
       
  1267 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1268 	CHECK(!re->FullMatchL(_L8("12345678901"), (TInt*)NULL));
       
  1269 	CleanupStack::PopAndDestroy(re);
       
  1270 	re = NULL;	
       
  1271 	
       
  1272 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1273 	CHECK(!re->FullMatchL(_L8("1234"), (TUint8*)NULL));
       
  1274 	CleanupStack::PopAndDestroy(re);
       
  1275 	re = NULL;	
       
  1276 
       
  1277 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1278 	CHECK(!re->FullMatchL(_L8("123456"), (TUint16*)NULL));
       
  1279 	CleanupStack::PopAndDestroy(re);
       
  1280 	re = NULL;	
       
  1281 	
       
  1282 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1283 	CHECK(!re->FullMatchL(_L8("12345678901"), (TUint32*)NULL));
       
  1284 	CleanupStack::PopAndDestroy(re);
       
  1285 	re = NULL;	
       
  1286 	
       
  1287 	re = CRegEx::NewLC(_L8("(.*)"));
       
  1288 	CHECK(!re->FullMatchL(_L8("12345678901"), (TUint*)NULL));
       
  1289 	CleanupStack::PopAndDestroy(re);
       
  1290 	re = NULL;	
       
  1291 
       
  1292 	// Ignored arg
       
  1293 	re = CRegEx::NewLC(_L8("(\\w+)(:)(\\d+)"));
       
  1294 	CHECK(re->FullMatchL(_L8("ruby:1234"), &s, (TAny*)NULL, &i));
       
  1295 	CleanupStack::PopAndDestroy(re);
       
  1296 	CHECK_EQ(s, _L8("ruby"));
       
  1297 	CHECK_EQ(i, 1234);
       
  1298 	re = NULL;		
       
  1299 
       
  1300 // Type tests
       
  1301 		{
       
  1302 		TChar c;
       
  1303 		re = CRegEx::NewLC(_L8("(H)ello"));
       
  1304 		CHECK(re->FullMatchL(_L8("Hello"), &c));
       
  1305 		CHECK_EQ(c, 'H');
       
  1306 		CleanupStack::PopAndDestroy(re);
       
  1307 		re = NULL;
       
  1308 		}
       
  1309 		{
       
  1310 		TInt8 v;
       
  1311 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1312 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1313 		CHECK_EQ(v, 100);
       
  1314 		CleanupStack::PopAndDestroy(re);
       
  1315 		re = NULL;
       
  1316 
       
  1317 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1318 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1319 		CHECK_EQ(v, -100);
       
  1320 		CleanupStack::PopAndDestroy(re);
       
  1321 		re = NULL;
       
  1322 
       
  1323 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1324 		CHECK(re->FullMatchL(_L8("127"), &v));
       
  1325 		CHECK_EQ(v, KMaxTInt8);
       
  1326 		CleanupStack::PopAndDestroy(re);
       
  1327 		re = NULL;
       
  1328 
       
  1329 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1330 		CHECK(re->FullMatchL(_L8("-128"), &v));
       
  1331 		CHECK_EQ(v, KMinTInt8);
       
  1332 		CleanupStack::PopAndDestroy(re);
       
  1333 		re = NULL;
       
  1334 
       
  1335 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1336 		CHECK(!re->FullMatchL(_L8("128"), &v));
       
  1337 		CleanupStack::PopAndDestroy(re);
       
  1338 		re = NULL;
       
  1339 
       
  1340 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1341 		CHECK(!re->FullMatchL(_L8("-129"), &v));
       
  1342 		CleanupStack::PopAndDestroy(re);
       
  1343 		re = NULL;
       
  1344 		}
       
  1345 		{
       
  1346 		TUint8 v;
       
  1347 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1348 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1349 		CHECK_EQ(v, 100);
       
  1350 		CleanupStack::PopAndDestroy(re);
       
  1351 		re = NULL;
       
  1352 
       
  1353 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1354 		CHECK(re->FullMatchL(_L8("128"), &v));
       
  1355 		CHECK_EQ(v, KMaxTInt8 + 1);
       
  1356 		CleanupStack::PopAndDestroy(re);
       
  1357 		re = NULL;
       
  1358 
       
  1359 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1360 		CHECK(re->FullMatchL(_L8("255"), &v));
       
  1361 		CHECK_EQ(v, KMaxTUint8);
       
  1362 		CleanupStack::PopAndDestroy(re);
       
  1363 		re = NULL;
       
  1364 
       
  1365 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1366 		CHECK(!re->FullMatchL(_L8("256"), &v));
       
  1367 		CleanupStack::PopAndDestroy(re);
       
  1368 		re = NULL;
       
  1369 
       
  1370 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1371 		CHECK(!re->FullMatchL(_L8("-100"), &v));
       
  1372 		CleanupStack::PopAndDestroy(re);
       
  1373 		re = NULL;
       
  1374 		}
       
  1375 		{
       
  1376 		TInt16 v;
       
  1377 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1378 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1379 		CHECK_EQ(v, 100);
       
  1380 		CleanupStack::PopAndDestroy(re);
       
  1381 		re = NULL;
       
  1382 
       
  1383 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1384 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1385 		CHECK_EQ(v, -100);
       
  1386 		CleanupStack::PopAndDestroy(re);
       
  1387 		re = NULL;
       
  1388 
       
  1389 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1390 		CHECK(re->FullMatchL(_L8("32767"), &v));
       
  1391 		CHECK_EQ(v, KMaxTInt16);
       
  1392 		CleanupStack::PopAndDestroy(re);
       
  1393 		re = NULL;
       
  1394 
       
  1395 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1396 		CHECK(re->FullMatchL(_L8("-32768"), &v));
       
  1397 		CHECK_EQ(v, KMinTInt16);
       
  1398 		CleanupStack::PopAndDestroy(re);
       
  1399 		re = NULL;
       
  1400 
       
  1401 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1402 		CHECK(!re->FullMatchL(_L8("32768"), &v));
       
  1403 		CleanupStack::PopAndDestroy(re);
       
  1404 		re = NULL;
       
  1405 
       
  1406 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1407 		CHECK(!re->FullMatchL(_L8("-32769"), &v));
       
  1408 		CleanupStack::PopAndDestroy(re);
       
  1409 		re = NULL;
       
  1410 		}
       
  1411 		{
       
  1412 		TUint16 v;
       
  1413 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1414 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1415 		CHECK_EQ(v, 100);
       
  1416 		CleanupStack::PopAndDestroy(re);
       
  1417 		re = NULL;
       
  1418 
       
  1419 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1420 		CHECK(re->FullMatchL(_L8("32767"), &v));
       
  1421 		CHECK_EQ(v, KMaxTInt16);
       
  1422 		CleanupStack::PopAndDestroy(re);
       
  1423 		re = NULL;
       
  1424 
       
  1425 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1426 		CHECK(re->FullMatchL(_L8("65535"), &v));
       
  1427 		CHECK_EQ(v, KMaxTUint16);
       
  1428 		CleanupStack::PopAndDestroy(re);
       
  1429 		re = NULL;
       
  1430 
       
  1431 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1432 		CHECK(!re->FullMatchL(_L8("655356"), &v));
       
  1433 		CleanupStack::PopAndDestroy(re);
       
  1434 		re = NULL;
       
  1435 		
       
  1436 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1437 		CHECK(!re->FullMatchL(_L8("-100"), &v));
       
  1438 		CleanupStack::PopAndDestroy(re);
       
  1439 		re = NULL;		
       
  1440 		}		
       
  1441 		{
       
  1442 		TInt32 v;
       
  1443 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1444 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1445 		CHECK_EQ(v, 100);
       
  1446 		CleanupStack::PopAndDestroy(re);
       
  1447 		re = NULL;
       
  1448 
       
  1449 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1450 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1451 		CHECK_EQ(v, -100);
       
  1452 		CleanupStack::PopAndDestroy(re);
       
  1453 		re = NULL;
       
  1454 
       
  1455 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1456 		CHECK(re->FullMatchL(_L8("2147483647"), &v));
       
  1457 		CHECK_EQ(v, KMaxTInt32);
       
  1458 		CleanupStack::PopAndDestroy(re);
       
  1459 		re = NULL;
       
  1460 
       
  1461 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1462 		CHECK(re->FullMatchL(_L8("-2147483648"), &v));
       
  1463 		CHECK_EQ(v, KMinTInt32);
       
  1464 		CleanupStack::PopAndDestroy(re);
       
  1465 		re = NULL;
       
  1466 
       
  1467 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1468 		CHECK(!re->FullMatchL(_L8("2147483648"), &v));
       
  1469 		CleanupStack::PopAndDestroy(re);
       
  1470 		re = NULL;
       
  1471 
       
  1472 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1473 		CHECK(!re->FullMatchL(_L8("-2147483649"), &v));
       
  1474 		CleanupStack::PopAndDestroy(re);
       
  1475 		re = NULL;
       
  1476 		}	
       
  1477 		{
       
  1478 		TUint32 v;
       
  1479 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1480 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1481 		CHECK_EQ(v, 100);
       
  1482 		CleanupStack::PopAndDestroy(re);
       
  1483 		re = NULL;
       
  1484 
       
  1485 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1486 		CHECK(re->FullMatchL(_L8("2147483647"), &v));
       
  1487 		CHECK_EQ(v, KMaxTInt32);
       
  1488 		CleanupStack::PopAndDestroy(re);
       
  1489 		re = NULL;
       
  1490 
       
  1491 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1492 		CHECK(re->FullMatchL(_L8("4294967295"), &v));
       
  1493 		CHECK_EQ(v, KMaxTUint32);
       
  1494 		CleanupStack::PopAndDestroy(re);
       
  1495 		re = NULL;
       
  1496 
       
  1497 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1498 		CHECK(!re->FullMatchL(_L8("4294967296"), &v));
       
  1499 		CleanupStack::PopAndDestroy(re);
       
  1500 		re = NULL;
       
  1501 		
       
  1502 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1503 		CHECK(!re->FullMatchL(_L8("-100"), &v));
       
  1504 		CleanupStack::PopAndDestroy(re);
       
  1505 		re = NULL;		
       
  1506 		}
       
  1507 		{
       
  1508 		TInt64 v;
       
  1509 		// Note  TLex treats TInt64 as unsigned
       
  1510 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1511 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1512 		CHECK_EQ(v, 100);
       
  1513 		CleanupStack::PopAndDestroy(re);
       
  1514 		re = NULL;
       
  1515 
       
  1516 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1517 		CHECK(re->FullMatchL(_L8("9223372036854775807"), &v));
       
  1518 		CHECK_EQ(v, KMaxTInt64);
       
  1519 		CleanupStack::PopAndDestroy(re);
       
  1520 		re = NULL;
       
  1521 
       
  1522 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1523 		CHECK(!re->FullMatchL(_L8("-100"), &v));
       
  1524 		CleanupStack::PopAndDestroy(re);
       
  1525 		re = NULL;
       
  1526 
       
  1527 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1528 		CHECK(!re->FullMatchL(_L8("-9223372036854775808"), &v));
       
  1529 		CleanupStack::PopAndDestroy(re);
       
  1530 		re = NULL;
       
  1531 
       
  1532 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1533 		CHECK(!re->FullMatchL(_L8("9223372036854775808"), &v));
       
  1534 		CleanupStack::PopAndDestroy(re);
       
  1535 		re = NULL;
       
  1536 
       
  1537 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1538 		CHECK(!re->FullMatchL(_L8("-9223372036854775809"), &v));
       
  1539 		CleanupStack::PopAndDestroy(re);
       
  1540 		re = NULL;
       
  1541 		}
       
  1542 		{
       
  1543 		TInt v;
       
  1544 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1545 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1546 		CHECK_EQ(v, 100);
       
  1547 		CleanupStack::PopAndDestroy(re);
       
  1548 		re = NULL;
       
  1549 
       
  1550 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1551 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1552 		CHECK_EQ(v, -100);
       
  1553 		CleanupStack::PopAndDestroy(re);
       
  1554 		re = NULL;
       
  1555 
       
  1556 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1557 		CHECK(re->FullMatchL(_L8("2147483647"), &v));
       
  1558 		CHECK_EQ(v, KMaxTInt);
       
  1559 		CleanupStack::PopAndDestroy(re);
       
  1560 		re = NULL;
       
  1561 
       
  1562 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1563 		CHECK(re->FullMatchL(_L8("-2147483648"), &v));
       
  1564 		CHECK_EQ(v, KMinTInt);
       
  1565 		CleanupStack::PopAndDestroy(re);
       
  1566 		re = NULL;
       
  1567 
       
  1568 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1569 		CHECK(!re->FullMatchL(_L8("2147483648"), &v));
       
  1570 		CleanupStack::PopAndDestroy(re);
       
  1571 		re = NULL;
       
  1572 
       
  1573 		re = CRegEx::NewLC(_L8("(-?\\d+)"));
       
  1574 		CHECK(!re->FullMatchL(_L8("-2147483649"), &v));
       
  1575 		CleanupStack::PopAndDestroy(re);
       
  1576 		re = NULL;
       
  1577 		}	
       
  1578 		{
       
  1579 		TUint v;
       
  1580 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1581 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1582 		CHECK_EQ(v, 100);		
       
  1583 		CleanupStack::PopAndDestroy(re);
       
  1584 		re = NULL;
       
  1585 
       
  1586 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1587 		CHECK(re->FullMatchL(_L8("2147483647"), &v));
       
  1588 		CHECK_EQ(v, KMaxTInt);
       
  1589 		CleanupStack::PopAndDestroy(re);
       
  1590 		re = NULL;
       
  1591 
       
  1592 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1593 		CHECK(re->FullMatchL(_L8("4294967295"), &v));
       
  1594 		CHECK_EQ(v, KMaxTUint);		
       
  1595 		CleanupStack::PopAndDestroy(re);
       
  1596 
       
  1597 		re = NULL;
       
  1598 
       
  1599 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1600 		CHECK(!re->FullMatchL(_L8("4294967296"), &v));
       
  1601 		CleanupStack::PopAndDestroy(re);
       
  1602 		re = NULL;
       
  1603 		
       
  1604 		re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1605 		CHECK(!re->FullMatchL(_L8("-100"), &v));
       
  1606 		CleanupStack::PopAndDestroy(re);
       
  1607 		re = NULL;		
       
  1608 		}		
       
  1609 		{
       
  1610 		TReal32 v;
       
  1611 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1612 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1613 		CHECK_EQ(v, 100);
       
  1614 		CleanupStack::PopAndDestroy(re);
       
  1615 		re = NULL;
       
  1616 
       
  1617 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1618 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1619 		CHECK_EQ(v, -100);
       
  1620 		CleanupStack::PopAndDestroy(re);
       
  1621 		re = NULL;
       
  1622 
       
  1623 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1624 		CHECK(re->FullMatchL(_L8("3.4028234663852885981170418348452e+38"), &v));
       
  1625 		CleanupStack::PopAndDestroy(re);
       
  1626 		re = NULL;
       
  1627 
       
  1628 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1629 		CHECK(re->FullMatchL(_L8("-1.17549435E-38f"), &v));
       
  1630 		CleanupStack::PopAndDestroy(re);
       
  1631 		re = NULL;
       
  1632 		}
       
  1633 		{
       
  1634 		TReal64 v;
       
  1635 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1636 		CHECK(re->FullMatchL(_L8("100"), &v));
       
  1637 		CHECK_EQ(v, 100);
       
  1638 		CleanupStack::PopAndDestroy(re);
       
  1639 		re = NULL;
       
  1640 
       
  1641 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1642 		CHECK(re->FullMatchL(_L8("-100"), &v));
       
  1643 		CHECK_EQ(v, -100);
       
  1644 		CleanupStack::PopAndDestroy(re);
       
  1645 		re = NULL;
       
  1646 
       
  1647 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1648 		CHECK(re->FullMatchL(_L8("1.7976931348623157E+308"), &v));
       
  1649 		CleanupStack::PopAndDestroy(re);
       
  1650 		re = NULL;
       
  1651 
       
  1652 		re = CRegEx::NewLC(_L8("(.*)"));
       
  1653 		CHECK(re->FullMatchL(_L8("-2.2250738585072015E-308"), &v));
       
  1654 		CleanupStack::PopAndDestroy(re);
       
  1655 		re = NULL;
       
  1656 		}
       
  1657 		
       
  1658 	// Check that matching is fully anchored
       
  1659 	re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1660 	CHECK(!re->FullMatchL(_L8("x1001"), &i));
       
  1661 	CleanupStack::PopAndDestroy(re);
       
  1662 	re = NULL;	
       
  1663 	
       
  1664 	re = CRegEx::NewLC(_L8("(\\d+)"));
       
  1665 	CHECK(!re->FullMatchL(_L8("1001x"), &i));
       
  1666 	CleanupStack::PopAndDestroy(re);
       
  1667 	re = NULL;		
       
  1668 	
       
  1669 	re = CRegEx::NewLC(_L8("x(\\d+)"));
       
  1670 	CHECK(re->FullMatchL(_L8("x1001"), &i));
       
  1671 	CleanupStack::PopAndDestroy(re);
       
  1672 	CHECK_EQ(i, 1001);
       
  1673 	re = NULL;		
       
  1674 	
       
  1675 	re = CRegEx::NewLC(_L8("(\\d+)x"));
       
  1676 	CHECK(re->FullMatchL(_L8("1001x"), &i));
       
  1677 	CleanupStack::PopAndDestroy(re);
       
  1678 	CHECK_EQ(i, 1001);
       
  1679 	re = NULL;
       
  1680 	
       
  1681 	// Braces
       
  1682 	re = CRegEx::NewLC(_L8("[0-9a-f+.-]{5,}"));
       
  1683 	CHECK(re->FullMatchL(_L8("0abcd")));
       
  1684 	CleanupStack::PopAndDestroy(re);
       
  1685 	re = NULL;
       
  1686 	
       
  1687 	re = CRegEx::NewLC(_L8("[0-9a-f+.-]{5,}"));
       
  1688 	CHECK(re->FullMatchL(_L8("0abcde")));
       
  1689 	CleanupStack::PopAndDestroy(re);
       
  1690 	re = NULL;
       
  1691 	
       
  1692 	re = CRegEx::NewLC(_L8("[0-9a-f+.-]{5,}"));
       
  1693 	CHECK(!re->FullMatchL(_L8("0abc")));
       
  1694 	CleanupStack::PopAndDestroy(re);
       
  1695 	re = NULL;
       
  1696 	
       
  1697 	// Complicated RE
       
  1698 	re = CRegEx::NewLC(_L8("foo|bar|[A-Z]"));
       
  1699 	CHECK(re->FullMatchL(_L8("foo")));
       
  1700 	CleanupStack::PopAndDestroy(re);
       
  1701 	re = NULL;
       
  1702 	
       
  1703 	re = CRegEx::NewLC(_L8("foo|bar|[A-Z]"));
       
  1704 	CHECK(re->FullMatchL(_L8("bar")));
       
  1705 	CleanupStack::PopAndDestroy(re);
       
  1706 	re = NULL;
       
  1707 	
       
  1708 	re = CRegEx::NewLC(_L8("foo|bar|[A-Z]"));
       
  1709 	CHECK(re->FullMatchL(_L8("X")));
       
  1710 	CleanupStack::PopAndDestroy(re);
       
  1711 	re = NULL;
       
  1712 	
       
  1713 	re = CRegEx::NewLC(_L8("foo|bar|[A-Z]"));
       
  1714 	CHECK(!re->FullMatchL(_L8("XY")));
       
  1715 	CleanupStack::PopAndDestroy(re);
       
  1716 	re = NULL;
       
  1717 	
       
  1718 	// Check full-match handling (needs '$' tacked on internally)
       
  1719 	re = CRegEx::NewLC(_L8("fo|foo"));
       
  1720 	CHECK(re->FullMatchL(_L8("fo")));
       
  1721 	CleanupStack::PopAndDestroy(re);
       
  1722 	re = NULL;
       
  1723 
       
  1724 	re = CRegEx::NewLC(_L8("fo|foo"));
       
  1725 	CHECK(re->FullMatchL(_L8("foo")));
       
  1726 	CleanupStack::PopAndDestroy(re);
       
  1727 	re = NULL;
       
  1728 
       
  1729 	re = CRegEx::NewLC(_L8("fo|foo$"));
       
  1730 	CHECK(re->FullMatchL(_L8("fo")));
       
  1731 	CleanupStack::PopAndDestroy(re);
       
  1732 	re = NULL;
       
  1733 
       
  1734 	re = CRegEx::NewLC(_L8("fo|foo$"));
       
  1735 	CHECK(re->FullMatchL(_L8("foo")));
       
  1736 	CleanupStack::PopAndDestroy(re);
       
  1737 	re = NULL;
       
  1738 
       
  1739 	re = CRegEx::NewLC(_L8("foo$"));
       
  1740 	CHECK(re->FullMatchL(_L8("foo")));
       
  1741 	CleanupStack::PopAndDestroy(re);
       
  1742 	re = NULL;
       
  1743 
       
  1744 	re = CRegEx::NewLC(_L8("foo\\$"));
       
  1745 	CHECK(!re->FullMatchL(_L8("foo$bar")));
       
  1746 	CleanupStack::PopAndDestroy(re);
       
  1747 	re = NULL;
       
  1748 
       
  1749 	re = CRegEx::NewLC(_L8("fo|bar"));
       
  1750 	CHECK(!re->FullMatchL(_L8("fox")));
       
  1751 	CleanupStack::PopAndDestroy(re);
       
  1752 	re = NULL;
       
  1753 
       
  1754 	// Uncomment the following if we change the handling of '$' to
       
  1755 	// prevent it from matching a trailing newline
       
  1756 	if (false)
       
  1757 		{
       
  1758 		// Check that we don't get bitten by pcre's special handling of a
       
  1759 		// '\n' at the end of the string matching '$'
       
  1760 		re = CRegEx::NewLC(_L8("foo$"));
       
  1761 		CHECK(!re->PartialMatchL(_L8("foo\n")));
       
  1762 		CleanupStack::PopAndDestroy(re);
       
  1763 		re = NULL;
       
  1764 		}
       
  1765 
       
  1766 	// Number of args
       
  1767 	TInt a[16];
       
  1768 
       
  1769 	re = CRegEx::NewLC(_L8(""));
       
  1770 	CHECK(re->FullMatchL(_L8("")));
       
  1771 	CleanupStack::PopAndDestroy(re);
       
  1772 	re = NULL;
       
  1773 
       
  1774 	memset(a, 0, sizeof(0));
       
  1775 	re = CRegEx::NewLC(_L8("(\\d){1}"));
       
  1776 	CHECK(re->FullMatchL(_L8("1"), &a[0]));
       
  1777 	CHECK_EQ(a[0], 1);
       
  1778 	CleanupStack::PopAndDestroy(re);
       
  1779 	re = NULL;
       
  1780 
       
  1781 	memset(a, 0, sizeof(0));
       
  1782 	re = CRegEx::NewLC(_L8("(\\d)(\\d)"));
       
  1783 	CHECK(re->FullMatchL(_L8("12"), &a[0], &a[1]));
       
  1784 	CHECK_EQ(a[0], 1);
       
  1785 	CHECK_EQ(a[1], 2);
       
  1786 	CleanupStack::PopAndDestroy(re);
       
  1787 	re = NULL;
       
  1788 
       
  1789 	memset(a, 0, sizeof(0));
       
  1790 	re = CRegEx::NewLC(_L8("(\\d)(\\d)(\\d)"));
       
  1791 	CHECK(re->FullMatchL(_L8("123"), &a[0], &a[1], &a[2]));
       
  1792 	CHECK_EQ(a[0], 1);
       
  1793 	CHECK_EQ(a[1], 2);
       
  1794 	CHECK_EQ(a[2], 3);
       
  1795 	CleanupStack::PopAndDestroy(re);
       
  1796 	re = NULL;
       
  1797 
       
  1798 	memset(a, 0, sizeof(0));
       
  1799 	re = CRegEx::NewLC(_L8("(\\d)(\\d)(\\d)(\\d)"));
       
  1800 	CHECK(re->FullMatchL(_L8("1234"), &a[0], &a[1], &a[2], &a[3]));
       
  1801 	CHECK_EQ(a[0], 1);
       
  1802 	CHECK_EQ(a[1], 2);
       
  1803 	CHECK_EQ(a[2], 3);
       
  1804 	CHECK_EQ(a[3], 4);
       
  1805 	CleanupStack::PopAndDestroy(re);
       
  1806 	re = NULL;
       
  1807 
       
  1808 	// Currently maximum args == 4
       
  1809 	/*
       
  1810 	memset(a, 0, sizeof(0));
       
  1811 	re = CRegEx::NewLC(_L8("(\\d)(\\d)(\\d)(\\d)(\\d)"));
       
  1812 	CHECK(re->FullMatchL(_L8("12345"), &a[0], &a[1], &a[2], &a[3], &a[4]));
       
  1813 	CHECK_EQ(a[0], 1);
       
  1814 	CHECK_EQ(a[1], 2);
       
  1815 	CHECK_EQ(a[2], 3);
       
  1816 	CHECK_EQ(a[3], 4);
       
  1817 	CHECK_EQ(a[4], 5);
       
  1818 	CleanupStack::PopAndDestroy(re);
       
  1819 	re = NULL;
       
  1820 
       
  1821 	memset(a, 0, sizeof(0));
       
  1822 	re = CRegEx::NewLC(_L8("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"));
       
  1823 	CHECK(re->FullMatchL(_L8("123456"), &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]));
       
  1824 	CHECK_EQ(a[0], 1);
       
  1825 	CHECK_EQ(a[1], 2);
       
  1826 	CHECK_EQ(a[2], 3);
       
  1827 	CHECK_EQ(a[3], 4);
       
  1828 	CHECK_EQ(a[4], 5);
       
  1829 	CHECK_EQ(a[5], 6);
       
  1830 	CleanupStack::PopAndDestroy(re);
       
  1831 	re = NULL;
       
  1832 
       
  1833 	memset(a, 0, sizeof(0));
       
  1834 	re = CRegEx::NewLC(_L8("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"));
       
  1835 	CHECK(re->FullMatchL(_L8("1234567"), &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]));
       
  1836 	CHECK_EQ(a[0], 1);
       
  1837 	CHECK_EQ(a[1], 2);
       
  1838 	CHECK_EQ(a[2], 3);
       
  1839 	CHECK_EQ(a[3], 4);
       
  1840 	CHECK_EQ(a[4], 5);
       
  1841 	CHECK_EQ(a[5], 6);
       
  1842 	CHECK_EQ(a[6], 7);
       
  1843 	CleanupStack::PopAndDestroy(re);
       
  1844 	re = NULL;
       
  1845 
       
  1846 	memset(a, 0, sizeof(0));
       
  1847 	re
       
  1848 			= CRegEx::NewLC(
       
  1849 					_L8("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"));
       
  1850 	CHECK(re->FullMatchL(_L8("1234567890123456"), &a[0], &a[1], &a[2], &a[3],
       
  1851 					&a[4], &a[5], &a[6], &a[7],
       
  1852 					&a[8], &a[9], &a[10], &a[11],
       
  1853 					&a[12],&a[13], &a[14], &a[15]));
       
  1854 	CHECK_EQ(a[0], 1);
       
  1855 	CHECK_EQ(a[1], 2);
       
  1856 	CHECK_EQ(a[2], 3);
       
  1857 	CHECK_EQ(a[3], 4);
       
  1858 	CHECK_EQ(a[4], 5);
       
  1859 	CHECK_EQ(a[5], 6);
       
  1860 	CHECK_EQ(a[6], 7);
       
  1861 	CHECK_EQ(a[7], 8);
       
  1862 	CHECK_EQ(a[8], 9);
       
  1863 	CHECK_EQ(a[9], 0);
       
  1864 	CHECK_EQ(a[10], 1);
       
  1865 	CHECK_EQ(a[11], 2);
       
  1866 	CHECK_EQ(a[12], 3);
       
  1867 	CHECK_EQ(a[13], 4);
       
  1868 	CHECK_EQ(a[14], 5);
       
  1869 	CHECK_EQ(a[15], 6);
       
  1870 	CleanupStack::PopAndDestroy(re);
       
  1871 	re = NULL;
       
  1872 	 */
       
  1873 	
       
  1874 	/***** PartialMatch *****/
       
  1875 	console->Write(_L("Testing PartialMatch\n"));
       
  1876 
       
  1877 	re = CRegEx::NewLC(_L8("h.*o"));
       
  1878 	CHECK(re->PartialMatchL(_L8("hello")));
       
  1879 	CleanupStack::PopAndDestroy(re);
       
  1880 	re = NULL;
       
  1881 
       
  1882 	re = CRegEx::NewLC(_L8("h.*o"));
       
  1883 	CHECK(re->PartialMatchL(_L8("othello")));
       
  1884 	CleanupStack::PopAndDestroy(re);
       
  1885 	re = NULL;
       
  1886 
       
  1887 	re = CRegEx::NewLC(_L8("h.*o"));
       
  1888 	CHECK(re->PartialMatchL(_L8("hello!")));
       
  1889 	CleanupStack::PopAndDestroy(re);
       
  1890 	re = NULL;
       
  1891 
       
  1892 	re = CRegEx::NewLC(_L8("((((((((((((((((((((x))))))))))))))))))))"));
       
  1893 	CHECK(re->PartialMatchL(_L8("x")));
       
  1894 	CleanupStack::PopAndDestroy(re);
       
  1895 	re = NULL;
       
  1896 
       
  1897 	/***** other tests *****/
       
  1898 
       
  1899 	RadixTestsL();
       
  1900 	TestReplaceL();
       
  1901 	TestExtractL();
       
  1902 	TestConsumeL();
       
  1903 	TestFindAndConsumeL();
       
  1904 	TestQuoteMetaAllL();
       
  1905 	TestMatchNumberPeculiarityL();
       
  1906 	
       
  1907 	// Check the pattern() accessor
       
  1908 		{
       
  1909 		_LIT8(KPattern, "http://([^/]+)/.*");
       
  1910 		re = CRegEx::NewLC(KPattern());
       
  1911 		CHECK_EQ(KPattern(), re->Pattern());
       
  1912 		CleanupStack::PopAndDestroy(re);
       
  1913 		re = NULL;
       
  1914 		}	
       
  1915 		// Check RE error field.
       
  1916 		{
       
  1917 		re = CRegEx::NewLC(_L8("foo"));
       
  1918 		CHECK_EQ(re->Error(), KErrNone);  // Must have no error
       
  1919 		CleanupStack::PopAndDestroy(re);
       
  1920 		re = NULL;
       
  1921 		}
       
  1922 		
       
  1923 #ifdef SUPPORT_UTF8
       
  1924 	  // Check UTF-8 handling
       
  1925 		{
       
  1926 		console->Write(_L("Testing UTF-8 handling\n"));
       
  1927 
       
  1928 		// Three Japanese characters (nihongo)
       
  1929 		TBuf8<9> utf8String(_L8("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"));
       
  1930 		TBuf8<5> utf8Pattern(_L8(".\xE6\x9C\xAC."));
       
  1931 		TRegExOptions utf8Options;
       
  1932 		utf8Options.SetUtf8(ETrue);	
       
  1933 	
       
  1934 		// Both should match in either mode, bytes or UTF-8
       
  1935 		CRegEx* re_test1 = CRegEx::NewLC(_L8("........."));
       
  1936 		CHECK(re_test1->FullMatchL(utf8String));
       
  1937 		CleanupStack::PopAndDestroy(re_test1);
       
  1938 		re_test1 = NULL;
       
  1939 		
       
  1940 		CRegEx* re_test2 = CRegEx::NewLC(_L8("..."), utf8Options);
       
  1941 		CHECK(re_test2->FullMatchL(utf8String));
       
  1942 		CleanupStack::PopAndDestroy(re_test2);
       
  1943 		re_test2 = NULL;		
       
  1944 
       
  1945 		// Check that '.' matches one byte or UTF-8 character
       
  1946 		// according to the mode.
       
  1947 		TBuf8<3> ss;
       
  1948 		
       
  1949 		CRegEx* re_test3 = CRegEx::NewLC(_L8("(.)"));
       
  1950 		CHECK(re_test3->PartialMatchL(utf8String, &ss));
       
  1951 		CHECK_EQ(ss, _L8("\xE6"));
       
  1952 		CleanupStack::PopAndDestroy(re_test3);
       
  1953 		re_test3 = NULL;	
       
  1954 		
       
  1955 		CRegEx* re_test4 = CRegEx::NewLC(_L8("(.)"), utf8Options);
       
  1956 		CHECK(re_test4->PartialMatchL(utf8String, &ss));
       
  1957 		CHECK_EQ(ss, _L8("\xE6\x97\xA5"));
       
  1958 		CleanupStack::PopAndDestroy(re_test4);
       
  1959 		re_test4 = NULL;	
       
  1960 		
       
  1961 		// Check that string matches itself in either mode
       
  1962 		CRegEx* re_test5 = CRegEx::NewLC(utf8String);
       
  1963 		CHECK(re_test5->FullMatchL(utf8String));
       
  1964 		CleanupStack::PopAndDestroy(re_test5);
       
  1965 		re_test5 = NULL;	
       
  1966 		
       
  1967 		CRegEx* re_test6 = CRegEx::NewLC(utf8String, utf8Options);
       
  1968 		CHECK(re_test6->FullMatchL(utf8String));
       
  1969 		CleanupStack::PopAndDestroy(re_test6);
       
  1970 		re_test6 = NULL;			
       
  1971 		
       
  1972 		// Check that pattern matches string only in UTF8 mode
       
  1973 		CRegEx* re_test7 = CRegEx::NewLC(utf8Pattern);
       
  1974 		CHECK(!re_test7->FullMatchL(utf8String));
       
  1975 		CleanupStack::PopAndDestroy(re_test7);
       
  1976 		re_test7 = NULL;
       
  1977 		
       
  1978 		CRegEx* re_test8 = CRegEx::NewLC(utf8Pattern, utf8Options);
       
  1979 		CHECK(re_test8->FullMatchL(utf8String));
       
  1980 		CleanupStack::PopAndDestroy(re_test8);
       
  1981 		re_test8 = NULL;
       
  1982 		}
       
  1983 
       
  1984 	// Check that ungreedy, UTF8 regular expressions don't match when they
       
  1985 	// oughtn't -- see bug 82246.
       
  1986 		{
       
  1987 		// This code always worked.
       
  1988 		_LIT8(KPattern, "\\w+X");
       
  1989 		_LIT8(KTarget, "a aX");
       
  1990 
       
  1991 		TRegExOptions utf8Options;
       
  1992 		utf8Options.SetUtf8(ETrue);	
       
  1993 		
       
  1994 		CRegEx* matchSentence = CRegEx::NewLC(KPattern());
       
  1995 		CHECK(!matchSentence->FullMatchL(KTarget()));
       
  1996 		CleanupStack::PopAndDestroy(matchSentence);
       
  1997 		matchSentence = NULL;
       
  1998 		
       
  1999 		CRegEx* matchSentenceRe = CRegEx::NewLC(KPattern(), utf8Options);
       
  2000 		CHECK(!matchSentenceRe->FullMatchL(KTarget()));
       
  2001 		CleanupStack::PopAndDestroy(matchSentenceRe);
       
  2002 		matchSentenceRe = NULL;
       
  2003 		}
       
  2004 		{
       
  2005 		_LIT8(KPattern, "(?U)\\w+X");
       
  2006 		_LIT8(KTarget, "a aX");
       
  2007 
       
  2008 		TRegExOptions utf8Options;
       
  2009 		utf8Options.SetUtf8(ETrue);	
       
  2010 		
       
  2011 		CRegEx* matchSentence = CRegEx::NewLC(KPattern());
       
  2012 		CHECK(!matchSentence->FullMatchL(KTarget()));
       
  2013 		CleanupStack::PopAndDestroy(matchSentence);
       
  2014 		matchSentence = NULL;
       
  2015 		
       
  2016 		CRegEx* matchSentenceRe = CRegEx::NewLC(KPattern(), utf8Options);
       
  2017 		CHECK(!matchSentenceRe->FullMatchL(KTarget()));
       
  2018 		CleanupStack::PopAndDestroy(matchSentenceRe);
       
  2019 		matchSentenceRe = NULL;
       
  2020 		}
       
  2021 		
       
  2022 #endif  /* def SUPPORT_UTF8 */	
       
  2023 
       
  2024   console->Write(_L("Testing error reporting\n"));
       
  2025 	  {
       
  2026 	  TRAPD(err, re = CRegEx::NewLC(_L8("a\\1")); CleanupStack::PopAndDestroy());
       
  2027 	  CHECK(err != KErrNone);
       
  2028 	  re = NULL;
       
  2029 	  }
       
  2030 	  {
       
  2031 	  TRAPD(err, re = CRegEx::NewLC(_L8("a[x")); CleanupStack::PopAndDestroy());
       
  2032 	  CHECK(err != KErrNone);
       
  2033 	  re = NULL;
       
  2034 	  }
       
  2035 	  {
       
  2036 	  TRAPD(err, re = CRegEx::NewLC(_L8("a[z-a]")); CleanupStack::PopAndDestroy());
       
  2037 	  CHECK(err != KErrNone);
       
  2038 	  re = NULL;
       
  2039 	  }
       
  2040 	  {
       
  2041 	  TRAPD(err, re = CRegEx::NewLC(_L8("a[[:foobar:]]")); CleanupStack::PopAndDestroy());
       
  2042 	  CHECK(err != KErrNone);
       
  2043 	  re = NULL;
       
  2044 	  }
       
  2045 	  {
       
  2046 	  TRAPD(err, re = CRegEx::NewLC(_L8("a(b")); CleanupStack::PopAndDestroy());
       
  2047 	  CHECK(err != KErrNone);
       
  2048 	  re = NULL;
       
  2049 	  }
       
  2050 	  {
       
  2051 	  TRAPD(err, re = CRegEx::NewLC(_L8("a\\")); CleanupStack::PopAndDestroy());
       
  2052 	  CHECK(err != KErrNone);
       
  2053 	  re = NULL;
       
  2054 	  }
       
  2055 	  
       
  2056 	  // Test that recursion is stopped
       
  2057 	  TestRecursionL();
       
  2058 	  
       
  2059 	  // Test Options
       
  2060 	  TestOptionsL();
       
  2061 
       
  2062 	  // Done
       
  2063 	  console->Write(_L("OK\n"));
       
  2064 	}
       
  2065 LOCAL_C void DoStartL()
       
  2066 	{
       
  2067 	// Create active scheduler (to run active objects)
       
  2068 	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
  2069 	CleanupStack::PushL(scheduler);
       
  2070 	CActiveScheduler::Install(scheduler);
       
  2071 
       
  2072 	MainL();
       
  2073 
       
  2074 	// Delete active scheduler
       
  2075 	CleanupStack::PopAndDestroy(scheduler);
       
  2076 	}
       
  2077 
       
  2078 //  Global Functions
       
  2079 
       
  2080 GLDEF_C TInt E32Main()
       
  2081 	{
       
  2082 	// Create cleanup stack
       
  2083 	__UHEAP_MARK;
       
  2084 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
  2085 	// Create output console
       
  2086 	TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(
       
  2087 							KConsFullScreen, KConsFullScreen)));
       
  2088 	if (createError)
       
  2089 		return createError;
       
  2090 	// Run application code inside TRAP harness, wait keypress when terminated
       
  2091 	TRAPD(mainError, DoStartL());
       
  2092 	if (mainError)
       
  2093 		console->Printf(KTextFailed, mainError);
       
  2094 	console->Printf(KTextPressAnyKey);
       
  2095 	console->Getch();
       
  2096 
       
  2097 	delete console;
       
  2098 	delete cleanup;
       
  2099 	__UHEAP_MARKEND;
       
  2100 	return KErrNone;
       
  2101 	}