/* ** 2008 March 19 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements new SQL functions used by the test scripts. */ #include "sqlite3.h" #include "tcl.h" #include #include #include /* ** Allocate nByte bytes of space using sqlite3_malloc(). If the ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed. */ static void *testContextMalloc(sqlite3_context *context, int nByte){ char *z = sqlite3_malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } return z; } /* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ static const unsigned char zSrc[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" ".-!,:*^+=_|?/<> "; int iMin, iMax, n, r, i; unsigned char zBuf[1000]; /* It used to be possible to call randstr() with any number of arguments, ** but now it is registered with SQLite as requiring exactly 2. */ assert(argc==2); iMin = sqlite3_value_int(argv[0]); if( iMin<0 ) iMin = 0; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; iMax = sqlite3_value_int(argv[1]); if( iMax=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; n = iMin; if( iMax>iMin ){ sqlite3_randomness(sizeof(r), &r); r &= 0x7fffffff; n += r%(iMax + 1 - iMin); } assert( n='0' && c<='9' ){ return c - '0'; }else if( c>='a' && c<='f' ){ return c - 'a' + 10; }else if( c>='A' && c<='F' ){ return c - 'A' + 10; } return 0; } /* ** Convert hex to binary. */ static void testHexToBin(const char *zIn, char *zOut){ while( zIn[0] && zIn[1] ){ *(zOut++) = (testHexChar(zIn[0])<<4) + testHexChar(zIn[1]); zIn += 2; } } /* ** hex_to_utf16be(HEX) ** ** Convert the input string from HEX into binary. Then return the ** result using sqlite3_result_text16le(). */ #ifndef SQLITE_OMIT_UTF16 static void testHexToUtf16be( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int n; const char *zIn; char *zOut; assert( nArg==1 ); n = sqlite3_value_bytes(argv[0]); zIn = (const char*)sqlite3_value_text(argv[0]); zOut = sqlite3_malloc( n/2 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); }else{ testHexToBin(zIn, zOut); sqlite3_result_text16be(pCtx, zOut, n/2, sqlite3_free); } } #endif /* ** hex_to_utf8(HEX) ** ** Convert the input string from HEX into binary. Then return the ** result using sqlite3_result_text16le(). */ static void testHexToUtf8( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int n; const char *zIn; char *zOut; assert( nArg==1 ); n = sqlite3_value_bytes(argv[0]); zIn = (const char*)sqlite3_value_text(argv[0]); zOut = sqlite3_malloc( n/2 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); }else{ testHexToBin(zIn, zOut); sqlite3_result_text(pCtx, zOut, n/2, sqlite3_free); } } /* ** hex_to_utf16le(HEX) ** ** Convert the input string from HEX into binary. Then return the ** result using sqlite3_result_text16le(). */ #ifndef SQLITE_OMIT_UTF16 static void testHexToUtf16le( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int n; const char *zIn; char *zOut; assert( nArg==1 ); n = sqlite3_value_bytes(argv[0]); zIn = (const char*)sqlite3_value_text(argv[0]); zOut = sqlite3_malloc( n/2 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); }else{ testHexToBin(zIn, zOut); sqlite3_result_text16le(pCtx, zOut, n/2, sqlite3_free); } } #endif static int registerTestFunctions(sqlite3 *db){ static const struct { char *zName; signed char nArg; unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */ void (*xFunc)(sqlite3_context*,int,sqlite3_value **); } aFuncs[] = { { "randstr", 2, SQLITE_UTF8, randStr }, { "test_destructor", 1, SQLITE_UTF8, test_destructor}, #ifndef SQLITE_OMIT_UTF16 { "test_destructor16", 1, SQLITE_UTF8, test_destructor16}, { "hex_to_utf16be", 1, SQLITE_UTF8, testHexToUtf16be}, { "hex_to_utf16le", 1, SQLITE_UTF8, testHexToUtf16le}, #endif { "hex_to_utf8", 1, SQLITE_UTF8, testHexToUtf8}, { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count}, { "test_auxdata", -1, SQLITE_UTF8, test_auxdata}, { "test_error", 1, SQLITE_UTF8, test_error}, { "test_error", 2, SQLITE_UTF8, test_error}, { "test_eval", 1, SQLITE_UTF8, test_eval}, { "test_isolation", 2, SQLITE_UTF8, test_isolation}, { "test_counter", 1, SQLITE_UTF8, counterFunc}, }; int i; for(i=0; i