sl@0: /* sl@0: ** 2001 September 15 sl@0: ** sl@0: ** The author disclaims copyright to this source code. In place of sl@0: ** a legal notice, here is a blessing: sl@0: ** sl@0: ** May you do good and not evil. sl@0: ** May you find forgiveness for yourself and forgive others. sl@0: ** May you share freely, never taking more than you give. sl@0: ** sl@0: ************************************************************************* sl@0: ** Code for testing the utf.c module in SQLite. This code sl@0: ** is not included in the SQLite library. It is used for automated sl@0: ** testing of the SQLite library. Specifically, the code in this file sl@0: ** is used for testing the SQLite routines for converting between sl@0: ** the various supported unicode encodings. sl@0: ** sl@0: ** $Id: test5.c,v 1.22 2008/08/12 15:04:59 danielk1977 Exp $ sl@0: */ sl@0: #include "sqliteInt.h" sl@0: #include "vdbeInt.h" sl@0: #include "tcl.h" sl@0: #include sl@0: #include sl@0: sl@0: /* sl@0: ** The first argument is a TCL UTF-8 string. Return the byte array sl@0: ** object with the encoded representation of the string, including sl@0: ** the NULL terminator. sl@0: */ sl@0: static int binarize( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: int len; sl@0: char *bytes; sl@0: Tcl_Obj *pRet; sl@0: assert(objc==2); sl@0: sl@0: bytes = Tcl_GetStringFromObj(objv[1], &len); sl@0: pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1); sl@0: Tcl_SetObjResult(interp, pRet); sl@0: return TCL_OK; sl@0: } sl@0: sl@0: /* sl@0: ** Usage: test_value_overhead . sl@0: ** sl@0: ** This routine is used to test the overhead of calls to sl@0: ** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea sl@0: ** is to figure out whether or not it is a problem to use sqlite3_value sl@0: ** structures with collation sequence functions. sl@0: ** sl@0: ** If is 0, then the calls to sqlite3_value_text() are not sl@0: ** actually made. sl@0: */ sl@0: static int test_value_overhead( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: int do_calls; sl@0: int repeat_count; sl@0: int i; sl@0: Mem val; sl@0: const char *zVal; sl@0: sl@0: if( objc!=3 ){ sl@0: Tcl_AppendResult(interp, "wrong # args: should be \"", sl@0: Tcl_GetStringFromObj(objv[0], 0), " ", 0); sl@0: return TCL_ERROR; sl@0: } sl@0: sl@0: if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR; sl@0: if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR; sl@0: sl@0: val.flags = MEM_Str|MEM_Term|MEM_Static; sl@0: val.z = "hello world"; sl@0: val.type = SQLITE_TEXT; sl@0: val.enc = SQLITE_UTF8; sl@0: sl@0: for(i=0; izName; pEnc++){ sl@0: if( 0==sqlite3StrICmp(z, pEnc->zName) ){ sl@0: break; sl@0: } sl@0: } sl@0: if( !pEnc->enc ){ sl@0: Tcl_AppendResult(interp, "No such encoding: ", z, 0); sl@0: } sl@0: if( pEnc->enc==SQLITE_UTF16 ){ sl@0: return SQLITE_UTF16NATIVE; sl@0: } sl@0: return pEnc->enc; sl@0: } sl@0: sl@0: /* sl@0: ** Usage: test_translate ?? sl@0: ** sl@0: */ sl@0: static int test_translate( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: u8 enc_from; sl@0: u8 enc_to; sl@0: sqlite3_value *pVal; sl@0: sl@0: char *z; sl@0: int len; sl@0: void (*xDel)(void *p) = SQLITE_STATIC; sl@0: sl@0: if( objc!=4 && objc!=5 ){ sl@0: Tcl_AppendResult(interp, "wrong # args: should be \"", sl@0: Tcl_GetStringFromObj(objv[0], 0), sl@0: " ", 0 sl@0: ); sl@0: return TCL_ERROR; sl@0: } sl@0: if( objc==5 ){ sl@0: xDel = sqlite3_free; sl@0: } sl@0: sl@0: enc_from = name_to_enc(interp, objv[2]); sl@0: if( !enc_from ) return TCL_ERROR; sl@0: enc_to = name_to_enc(interp, objv[3]); sl@0: if( !enc_to ) return TCL_ERROR; sl@0: sl@0: pVal = sqlite3ValueNew(0); sl@0: sl@0: if( enc_from==SQLITE_UTF8 ){ sl@0: z = Tcl_GetString(objv[1]); sl@0: if( objc==5 ){ sl@0: z = sqlite3DbStrDup(0, z); sl@0: } sl@0: sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); sl@0: }else{ sl@0: z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); sl@0: if( objc==5 ){ sl@0: char *zTmp = z; sl@0: z = sqlite3_malloc(len); sl@0: memcpy(z, zTmp, len); sl@0: } sl@0: sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); sl@0: } sl@0: sl@0: z = (char *)sqlite3ValueText(pVal, enc_to); sl@0: len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2); sl@0: Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len)); sl@0: sl@0: sqlite3ValueFree(pVal); sl@0: sl@0: return TCL_OK; sl@0: } sl@0: sl@0: /* sl@0: ** Usage: translate_selftest sl@0: ** sl@0: ** Call sqlite3UtfSelfTest() to run the internal tests for unicode sl@0: ** translation. If there is a problem an assert() will fail. sl@0: **/ sl@0: void sqlite3UtfSelfTest(void); sl@0: static int test_translate_selftest( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: #ifndef SQLITE_OMIT_UTF16 sl@0: sqlite3UtfSelfTest(); sl@0: #endif sl@0: return SQLITE_OK; sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** Register commands with the TCL interpreter. sl@0: */ sl@0: int Sqlitetest5_Init(Tcl_Interp *interp){ sl@0: static struct { sl@0: char *zName; sl@0: Tcl_ObjCmdProc *xProc; sl@0: } aCmd[] = { sl@0: { "binarize", (Tcl_ObjCmdProc*)binarize }, sl@0: { "test_value_overhead", (Tcl_ObjCmdProc*)test_value_overhead }, sl@0: { "test_translate", (Tcl_ObjCmdProc*)test_translate }, sl@0: { "translate_selftest", (Tcl_ObjCmdProc*)test_translate_selftest}, sl@0: }; sl@0: int i; sl@0: for(i=0; i