1 /* 2 ** 2007 March 29 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** 13 ** This file contains obscure tests of the C-interface required 14 ** for completeness. Test code is written in C for these cases 15 ** as there is not much point in binding to Tcl. 16 */ 17 #include "sqliteInt.h" 18 #if defined(INCLUDE_SQLITE_TCL_H) 19 # include "sqlite_tcl.h" 20 #else 21 # include "tcl.h" 22 #endif 23 #include <stdlib.h> 24 #include <string.h> 25 26 /* 27 ** c_collation_test 28 */ 29 static int SQLITE_TCLAPI c_collation_test( 30 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 31 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 32 int objc, /* Number of arguments */ 33 Tcl_Obj *CONST objv[] /* Command arguments */ 34 ){ 35 const char *zErrFunction = "N/A"; 36 sqlite3 *db; 37 38 int rc; 39 if( objc!=1 ){ 40 Tcl_WrongNumArgs(interp, 1, objv, ""); 41 return TCL_ERROR; 42 } 43 44 /* Open a database. */ 45 rc = sqlite3_open(":memory:", &db); 46 if( rc!=SQLITE_OK ){ 47 zErrFunction = "sqlite3_open"; 48 goto error_out; 49 } 50 51 rc = sqlite3_create_collation(db, "collate", 456, 0, 0); 52 if( rc!=SQLITE_MISUSE ){ 53 sqlite3_close(db); 54 zErrFunction = "sqlite3_create_collation"; 55 goto error_out; 56 } 57 58 sqlite3_close(db); 59 return TCL_OK; 60 61 error_out: 62 Tcl_ResetResult(interp); 63 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0); 64 return TCL_ERROR; 65 } 66 67 /* 68 ** c_realloc_test 69 */ 70 static int SQLITE_TCLAPI c_realloc_test( 71 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 72 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 73 int objc, /* Number of arguments */ 74 Tcl_Obj *CONST objv[] /* Command arguments */ 75 ){ 76 void *p; 77 const char *zErrFunction = "N/A"; 78 79 if( objc!=1 ){ 80 Tcl_WrongNumArgs(interp, 1, objv, ""); 81 return TCL_ERROR; 82 } 83 84 p = sqlite3_malloc(5); 85 if( !p ){ 86 zErrFunction = "sqlite3_malloc"; 87 goto error_out; 88 } 89 90 /* Test that realloc()ing a block of memory to a negative size is 91 ** the same as free()ing that memory. 92 */ 93 p = sqlite3_realloc(p, -1); 94 if( p ){ 95 zErrFunction = "sqlite3_realloc"; 96 goto error_out; 97 } 98 99 return TCL_OK; 100 101 error_out: 102 Tcl_ResetResult(interp); 103 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0); 104 return TCL_ERROR; 105 } 106 107 108 /* 109 ** c_misuse_test 110 */ 111 static int SQLITE_TCLAPI c_misuse_test( 112 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 113 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 114 int objc, /* Number of arguments */ 115 Tcl_Obj *CONST objv[] /* Command arguments */ 116 ){ 117 const char *zErrFunction = "N/A"; 118 sqlite3 *db = 0; 119 sqlite3_stmt *pStmt; 120 int rc; 121 122 if( objc!=1 ){ 123 Tcl_WrongNumArgs(interp, 1, objv, ""); 124 return TCL_ERROR; 125 } 126 127 /* Open a database. Then close it again. We need to do this so that 128 ** we have a "closed database handle" to pass to various API functions. 129 */ 130 rc = sqlite3_open(":memory:", &db); 131 if( rc!=SQLITE_OK ){ 132 zErrFunction = "sqlite3_open"; 133 goto error_out; 134 } 135 sqlite3_close(db); 136 137 138 rc = sqlite3_errcode(db); 139 if( rc!=SQLITE_MISUSE ){ 140 zErrFunction = "sqlite3_errcode"; 141 goto error_out; 142 } 143 144 pStmt = (sqlite3_stmt*)1234; 145 rc = sqlite3_prepare(db, 0, 0, &pStmt, 0); 146 if( rc!=SQLITE_MISUSE ){ 147 zErrFunction = "sqlite3_prepare"; 148 goto error_out; 149 } 150 assert( pStmt==0 ); /* Verify that pStmt is zeroed even on a MISUSE error */ 151 152 pStmt = (sqlite3_stmt*)1234; 153 rc = sqlite3_prepare_v2(db, 0, 0, &pStmt, 0); 154 if( rc!=SQLITE_MISUSE ){ 155 zErrFunction = "sqlite3_prepare_v2"; 156 goto error_out; 157 } 158 assert( pStmt==0 ); 159 160 #ifndef SQLITE_OMIT_UTF16 161 pStmt = (sqlite3_stmt*)1234; 162 rc = sqlite3_prepare16(db, 0, 0, &pStmt, 0); 163 if( rc!=SQLITE_MISUSE ){ 164 zErrFunction = "sqlite3_prepare16"; 165 goto error_out; 166 } 167 assert( pStmt==0 ); 168 pStmt = (sqlite3_stmt*)1234; 169 rc = sqlite3_prepare16_v2(db, 0, 0, &pStmt, 0); 170 if( rc!=SQLITE_MISUSE ){ 171 zErrFunction = "sqlite3_prepare16_v2"; 172 goto error_out; 173 } 174 assert( pStmt==0 ); 175 #endif 176 177 return TCL_OK; 178 179 error_out: 180 Tcl_ResetResult(interp); 181 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0); 182 return TCL_ERROR; 183 } 184 185 /* 186 ** Register commands with the TCL interpreter. 187 */ 188 int Sqlitetest9_Init(Tcl_Interp *interp){ 189 static struct { 190 char *zName; 191 Tcl_ObjCmdProc *xProc; 192 void *clientData; 193 } aObjCmd[] = { 194 { "c_misuse_test", c_misuse_test, 0 }, 195 { "c_realloc_test", c_realloc_test, 0 }, 196 { "c_collation_test", c_collation_test, 0 }, 197 }; 198 int i; 199 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 200 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 201 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 202 } 203 return TCL_OK; 204 } 205