1 /* 2 ** 2019 April 02 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 */ 14 #if SQLITE_TEST /* This file is used for testing only */ 15 16 #include "sqlite3.h" 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 24 #ifdef SQLITE_VDBE_COVERAGE 25 26 static u8 aBranchArray[200000]; 27 28 static void test_vdbe_branch( 29 void *pCtx, 30 unsigned int iSrc, 31 unsigned char iBranch, 32 unsigned char iType 33 ){ 34 if( iSrc<sizeof(aBranchArray) ){ 35 aBranchArray[iSrc] |= iBranch; 36 } 37 } 38 39 static void appendToList( 40 Tcl_Obj *pList, 41 int iLine, 42 int iPath, 43 const char *zNever 44 ){ 45 Tcl_Obj *pNew = Tcl_NewObj(); 46 Tcl_IncrRefCount(pNew); 47 Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iLine)); 48 Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iPath)); 49 Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zNever, -1)); 50 Tcl_ListObjAppendElement(0, pList, pNew); 51 Tcl_DecrRefCount(pNew); 52 } 53 54 55 static int SQLITE_TCLAPI test_vdbe_coverage( 56 ClientData cd, 57 Tcl_Interp *interp, 58 int objc, 59 Tcl_Obj *CONST objv[] 60 ){ 61 const char *aSub[] = { "start", "report", "stop", 0 }; 62 int iSub = -1; 63 if( objc!=2 ){ 64 Tcl_WrongNumArgs(interp, 1, objv, "sub-command"); 65 return TCL_ERROR; 66 } 67 68 if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){ 69 return TCL_ERROR; 70 } 71 72 Tcl_ResetResult(interp); 73 assert( iSub==0 || iSub==1 || iSub==2 ); 74 switch( iSub ){ 75 case 0: /* start */ 76 memset(aBranchArray, 0, sizeof(aBranchArray)); 77 sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, test_vdbe_branch, 0); 78 break; 79 case 1: { /* report */ 80 int i; 81 Tcl_Obj *pRes = Tcl_NewObj(); 82 Tcl_IncrRefCount(pRes); 83 for(i=0; i<sizeof(aBranchArray); i++){ 84 u8 b = aBranchArray[i]; 85 int bFlag = ((b >> 4)==4); 86 if( b ){ 87 if( (b & 0x01)==0 ){ 88 appendToList(pRes, i, 0, bFlag ? "less than" : "falls through"); 89 } 90 if( (b & 0x02)==0 ){ 91 appendToList(pRes, i, 1, bFlag ? "equal" : "taken"); 92 } 93 if( (b & 0x04)==0 ){ 94 appendToList(pRes, i, 2, bFlag ? "greater-than" : "NULL"); 95 } 96 } 97 } 98 Tcl_SetObjResult(interp, pRes); 99 Tcl_DecrRefCount(pRes); 100 break; 101 }; 102 103 default: /* stop */ 104 sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0); 105 break; 106 } 107 108 return TCL_OK; 109 } 110 111 #endif /* SQLITE_VDBE_COVERAGE */ 112 113 int Sqlitetestvdbecov_Init(Tcl_Interp *interp){ 114 #ifdef SQLITE_VDBE_COVERAGE 115 Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0); 116 #endif 117 return TCL_OK; 118 } 119 120 #endif 121