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