summaryrefslogtreecommitdiffstats
path: root/src/test_vdbecov.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test_vdbecov.c')
-rw-r--r--src/test_vdbecov.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/test_vdbecov.c b/src/test_vdbecov.c
new file mode 100644
index 0000000..a001b1d
--- /dev/null
+++ b/src/test_vdbecov.c
@@ -0,0 +1,120 @@
+/*
+** 2019 April 02
+**
+** 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.
+**
+******************************************************************************
+**
+*/
+#if SQLITE_TEST /* This file is used for testing only */
+
+#include "sqlite3.h"
+#include "sqliteInt.h"
+#if defined(INCLUDE_SQLITE_TCL_H)
+# include "sqlite_tcl.h"
+#else
+# include "tcl.h"
+#endif
+
+#ifdef SQLITE_VDBE_COVERAGE
+
+static u8 aBranchArray[200000];
+
+static void test_vdbe_branch(
+ void *pCtx,
+ unsigned int iSrc,
+ unsigned char iBranch,
+ unsigned char iType
+){
+ if( iSrc<sizeof(aBranchArray) ){
+ aBranchArray[iSrc] |= iBranch;
+ }
+}
+
+static void appendToList(
+ Tcl_Obj *pList,
+ int iLine,
+ int iPath,
+ const char *zNever
+){
+ Tcl_Obj *pNew = Tcl_NewObj();
+ Tcl_IncrRefCount(pNew);
+ Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iLine));
+ Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iPath));
+ Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zNever, -1));
+ Tcl_ListObjAppendElement(0, pList, pNew);
+ Tcl_DecrRefCount(pNew);
+}
+
+
+static int SQLITE_TCLAPI test_vdbe_coverage(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ const char *aSub[] = { "start", "report", "stop", 0 };
+ int iSub = -1;
+ if( objc!=2 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "sub-command");
+ return TCL_ERROR;
+ }
+
+ if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){
+ return TCL_ERROR;
+ }
+
+ Tcl_ResetResult(interp);
+ assert( iSub==0 || iSub==1 || iSub==2 );
+ switch( iSub ){
+ case 0: /* start */
+ memset(aBranchArray, 0, sizeof(aBranchArray));
+ sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, test_vdbe_branch, 0);
+ break;
+ case 1: { /* report */
+ int i;
+ Tcl_Obj *pRes = Tcl_NewObj();
+ Tcl_IncrRefCount(pRes);
+ for(i=0; i<sizeof(aBranchArray); i++){
+ u8 b = aBranchArray[i];
+ int bFlag = ((b >> 4)==4);
+ if( b ){
+ if( (b & 0x01)==0 ){
+ appendToList(pRes, i, 0, bFlag ? "less than" : "falls through");
+ }
+ if( (b & 0x02)==0 ){
+ appendToList(pRes, i, 1, bFlag ? "equal" : "taken");
+ }
+ if( (b & 0x04)==0 ){
+ appendToList(pRes, i, 2, bFlag ? "greater-than" : "NULL");
+ }
+ }
+ }
+ Tcl_SetObjResult(interp, pRes);
+ Tcl_DecrRefCount(pRes);
+ break;
+ };
+
+ default: /* stop */
+ sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0);
+ break;
+ }
+
+ return TCL_OK;
+}
+
+#endif /* SQLITE_VDBE_COVERAGE */
+
+int Sqlitetestvdbecov_Init(Tcl_Interp *interp){
+#ifdef SQLITE_VDBE_COVERAGE
+ Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0);
+#endif
+ return TCL_OK;
+}
+
+#endif