diff -r 000000000000 -r e4d67989cc36 genericopenlibs/cstdlib/TSTLIB/TMISC.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cstdlib/TSTLIB/TMISC.CPP Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,733 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// This test has been converted from it original TMISC.C . +// The original was a manaul test and didn't work! +// Test code for bsearch, qsort etc. These are all functions which work directly +// without using the MSystemInterface - as such none of them use errno to indicate +// errors. +// +// + +#include +#include + +#include +#include +#include +#include /* HUGE_VAL */ +#include /* ERANGE */ +#include "ESTLIB.H" + +// Defined in ctest.h but contains lots of other declarations we don't want +#define test_Data struct __testdata __td /* declares global variable __td */ + +// +// Globals + +static RTest TheTest(_L("TMisc")); + +// +// +//Test macroses and functions + +static void Check(TInt aValue, TInt aLine) + { + if(!aValue) + { + TheTest(EFalse, aLine); + } + } +static void Check(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); + TheTest(EFalse, aLine); + } + } + +#define TEST(arg) ::Check((arg), __LINE__) +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) + +// +// Tests + + +/* random numbers */ + +void random_numbers() + { + int i,r; + int rs[20]; + + TheTest.Next(_L("Random numbers")); + + for (i=0; i<20; i++) + { + r = rand(); + printf("%d ", r); + } + printf("\n"); + TheTest.Next(_L("Using srand()")); + srand(12345678); + for (i=0; i<20; i++) + { + rs[i]=rand(); + printf("%d ",rs[i]); + } + printf("\n"); + srand(12345678); + for (i=0; i<20; i++) + TEST(rand()==rs[i]); + } + +/* Sorting */ + +typedef struct { + int a; + int b; + int c; + } sort_item; + +int compare_a (const void *left, const void *right) + { + sort_item *lp = (sort_item *)left; + sort_item *rp = (sort_item *)right; + + if (lp->a < rp->a) return -1; + if (lp->a > rp->a) return 1; + return 0; + } + +int compare_ba (const void *left, const void *right) + { + sort_item *lp = (sort_item *)left; + sort_item *rp = (sort_item *)right; + + if (lp->b < rp->b) return -1; + if (lp->b > rp->b) return 1; + /* b's are equal, sort on a's */ + if (lp->a < rp->a) return -1; + if (lp->a > rp->a) return 1; + return 0; + } + +#define NITEMS 200 +sort_item list[NITEMS]; + +void validate(sort_item *p) + { + int i; + for (i=0; ia==9) + continue; + TEST((p->a/4)+p->b == 5000); + TEST((p->a*p->a)/4 == p->c); + } + } + +void sorting() + { + int i; + TheTest.Next(_L("Quicksort")); + for (i=1; i +#include + +jmp_buf jbufs[4]; +int count=0; + +static int getStackPointer(void) + { + static char there; + char here; + return &here-&there; + } + +static int getgetStackPointer(void) + { + int n=4; // local variable to cause change to stack pointer + n+=getStackPointer(); + if (n==0) + n=getStackPointer()+37; // this never happens - it's just to defeat the optimiser + return (n-4); + } + +void jmp_nest(int n) + { + int m=n+100; // local variable to induce a stack frame + if (n>0) + jmp_nest(n-1); + longjmp(jbufs[3],m); + } + +#ifdef __VC32__ +#pragma optimize( "", off ) //stop the compiler breaking this TEST +#endif + +void setjmp_longjmp() + { + volatile int i,r,j,k,l,m; // volatile to rid us of warnings + volatile int sp1,sp2; + TheTest.Next(_L("Setjmp")); + + sp1=getStackPointer(); + sp2=getgetStackPointer(); + TEST(sp1!=sp2); // call from deeper function nesting should give a different answer + + memset(jbufs[0],0,sizeof(jmp_buf)); + memset(jbufs[1],0,sizeof(jmp_buf)); + memset(jbufs[2],0,sizeof(jmp_buf)); + + r=setjmp(jbufs[0]); + TEST(r==0); + + for (i=0,j=1,k=2,l=3,m=4; i<3; i++,j*=3,k+=j,l*=m,m-=2) + { + r=setjmp(jbufs[i]); + TEST(r==0); + TEST(j>i); + } + r=memcmp(jbufs[0],jbufs[2], sizeof(jmp_buf)); + + if (r!=0) + { + RDebug::Print(_L(" Test code appears to be using preserved registers (a good thing)\n")); + RDebug::Print(_L(" buf @ %08x %08x\n"), jbufs[0], jbufs[2]); + for (i=0;i<16;i++) + { + if (jbufs[0][i] != jbufs[2][i]) + RDebug::Print(_L(" buf+%02d: %08x %08x\n"), i*4, jbufs[0][i], jbufs[2][i]); + } + } + else + RDebug::Print(_L(" Test code appears not to exercise preserved registers\n")); + + r=setjmp(jbufs[0]); + TEST(r==0); + r=setjmp(jbufs[2]); + TEST(r==0); + r=memcmp(jbufs[0],jbufs[2], sizeof(jmp_buf)); + TEST(r!=0); /* must change the return address! */ + + TheTest.Next(_L("Setjmp and longjmp")); + + r=setjmp(jbufs[0]); + if (r==0) + { + TEST(count==0); + count++; + longjmp(jbufs[0],7); + } + else if (r==7) + { + TEST(count==1); + count++; + longjmp(jbufs[0],3); + } + else if (r==3) + { + TEST(count==2); + count++; + longjmp(jbufs[0],0); /* 0 must be turned into 1 */ + } + else + { + TEST(r==1); + TEST(count==3); + count++; + } + + sp1=getStackPointer(); + r=setjmp(jbufs[3]); + if (r==0) + { + sp2=getStackPointer(); + TEST(sp1==sp2); + longjmp(jbufs[3],1); // simple setjmp/longjmp + } + else if (r==1) + { + sp2=getStackPointer(); + TEST(sp1==sp2); + jmp_nest(20); // more complex example + } + else + { + TEST(r==100); + sp2=getStackPointer(); + TEST(sp1==sp2); + } + } + +#ifdef __VC32__ +#pragma optimize( "", on ) //stop the compiler breaking this TEST +#endif + +/* case-insensitive comparison */ + +#include +char agrave[2]= {191,0}; + +void casecmp() + { + int r; + char *s1,*s2; + TheTest.Next(_L("Case-insensitive string comparison")); + + s1="abcd"; + r=strcasecmp(s1,s1); + TEST(r==0); + + s2="abcde"; + r=strcasecmp(s1,s2); + TEST(r<0); + + r=strcasecmp(s2,s1); + TEST(r>0); + + r=strncasecmp(s1,s2,10); + TEST(r<0); + + r=strncasecmp(s1,s2,4); + TEST(r==0); + + s2="ABcD"; + r=strcmp(s1,s2); + TEST(r!=0); + r=strcasecmp(s1,s2); + TEST(r==0); + +#if 0 + /* Need some way to set up a proper folding example */ + r=strncasecmp(s2,agrave,1); + TEST(r==0); +#endif + } + +void arguments(int argc, char *argv[]) + { + int i; + + TheTest.Next(_L("Command line arguments")); + TEST(argc>0); + TEST(argv!=0); + printf(" argc=%d\r\n", argc); + for (i=0; isource; dc++) + { + d=strtod(dc->source,NULL); + TEST(d==dc->answer); + } + for (dc=strtods; dc->source; dc++) + { + p=(char*)1; + d=strtod(dc->source,&p); + TEST(d==dc->answer); + TEST(p==dc->source+dc->tail_offset); + } + + /* overflow positive number */ + d=strtod("9e9999", NULL); + TEST(d==HUGE_VAL && errno==ERANGE); + + /* overflow negative number */ + d=strtod("-9e9999", NULL); + TEST(d==-HUGE_VAL && errno==ERANGE); + + /* underflow number */ + d=strtod("9e-9999", NULL); + TEST(d==0 && errno==ERANGE); + d=strtod("-9e-9999", NULL); + TEST(d==0 && errno==ERANGE); +} + +#define TEST_8 0x88 +#define TEST_16 0x1617 +#define TEST_32 0x32333435 + +#define TEST_LIST \ + TEST_8, TEST_16, TEST_32, \ + TEST_8, TEST_32, TEST_16, \ + TEST_16, TEST_8, TEST_32, \ + TEST_16, TEST_32, TEST_8, \ + TEST_32, TEST_8, TEST_16, \ + TEST_32, TEST_16, TEST_8 + +/* + Suppressing RVCT compiler warning (for char/short/long types): + Warning: #1256-D: "unsigned char" would have been promoted to "int" when passed through the ellipsis parameter; + use the latter type instead. + b = va_arg(ap, unsigned char); + ^ +*/ + +#pragma diag_suppress 1256 + +// The above RCVT warning is a compiler error in GCC. Below is the GGC friendly version of the function. +#ifdef __GCC32__ + +void va_va_bwlblwwblwlblbwlwb(va_list ap) + { + unsigned long l; + unsigned short w; + unsigned char b; + + l=0; w=0; b=0; + b = va_arg(ap, int); + TEST(b==TEST_8); + w = va_arg(ap, int); + TEST(w==TEST_16); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + + l=0; w=0; b=0; + b = va_arg(ap, int); + TEST(b==TEST_8); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + w = va_arg(ap, int); + TEST(w==TEST_16); + + l=0; w=0; b=0; + w = va_arg(ap, int); + TEST(w==TEST_16); + b = va_arg(ap, int); + TEST(b==TEST_8); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + + l=0; w=0; b=0; + w = va_arg(ap,int); + TEST(w==TEST_16); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + b = va_arg(ap, int); + TEST(b==TEST_8); + + l=0; w=0; b=0; + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + b = va_arg(ap, int); + TEST(b==TEST_8); + w = va_arg(ap, int); + TEST(w==TEST_16); + + l=0; w=0; b=0; + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + w = va_arg(ap, int); + TEST(w==TEST_16); + b = va_arg(ap, int); + TEST(b==TEST_8); + } + + +#else + +void va_va_bwlblwwblwlblbwlwb(va_list ap) + { + unsigned long l; + unsigned short w; + unsigned char b; + + l=0; w=0; b=0; + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + + l=0; w=0; b=0; + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + + l=0; w=0; b=0; + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + + l=0; w=0; b=0; + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + + l=0; w=0; b=0; + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + + l=0; w=0; b=0; + l = va_arg(ap, unsigned long); + TEST(l==TEST_32); + w = va_arg(ap, unsigned short); + TEST(w==TEST_16); + b = va_arg(ap, unsigned char); + TEST(b==TEST_8); + } + +#endif + + +#pragma diag_default 1256 + +void va_lbwlblwwblwlblbwlwb(unsigned long x, ...) + { + va_list ap; + TEST(x==TEST_32); + va_start(ap, x); + + va_va_bwlblwwblwlblbwlwb(ap); + } + +void va_args_test() + { + TheTest.Next(_L("variadic functions")); + + va_lbwlblwwblwlblbwlwb( TEST_32, TEST_LIST); + } + +void sprintf_test() + { + char buf[256]; + char* hw = "hello, world"; + + TheTest.Next(_L("sprintf function")); + + /* WAP TOG Defect */ + sprintf(buf, "%.*f", 0, 10.1234); + TEST(strcmp(buf, "10")==0); + sprintf(buf, "%.0f", 10.1234); + TEST(strcmp(buf, "10")==0); + + /* From K&R */ + sprintf(buf, ":%s:", hw); + TEST(strcmp(buf, ":hello, world:")==0); + + sprintf(buf, ":%10s:", hw); + TEST(strcmp(buf, ":hello, world:")==0); + + sprintf(buf, ":%.10s:", hw); + TEST(strcmp(buf, ":hello, wor:")==0); + + sprintf(buf, ":%-10s:", hw); + TEST(strcmp(buf, ":hello, world:")==0); + + sprintf(buf, ":%.15s:", hw); + TEST(strcmp(buf, ":hello, world:")==0); + + sprintf(buf, ":%-15s:", hw); + TEST(strcmp(buf, ":hello, world :")==0); + + sprintf(buf, ":%15.10s:", hw); + TEST(strcmp(buf, ": hello, wor:")==0); + + sprintf(buf, ":%-15.10s:", hw); + TEST(strcmp(buf, ":hello, wor :")==0); + } + + +static void MainL() + { + TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-STDLIB-LEGACY-TMISC-0001 TMISC tests ")); + + random_numbers(); + sorting(); + searching(); + setjmp_longjmp(); + casecmp(); + sscanf_test(); + + int argsc = 5; + char *argsv[]= + { + "tmisc", "This", "is", "a", "test.", + }; + arguments(argsc, argsv); + + strtod_test(); + va_args_test(); + sprintf_test(); + } + + +TInt E32Main() + { + __UHEAP_MARK; + + CTrapCleanup* tc = CTrapCleanup::New(); + TEST(tc != NULL); + + TheTest.Title(); + TRAPD(err, ::MainL()); + TEST2(err, KErrNone); + + TheTest.End(); + TheTest.Close(); + + delete tc; + CloseSTDLIB(); + + __UHEAP_MARKEND; + + User::Heap().Check(); + return KErrNone; + }