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