aboutsummaryrefslogtreecommitdiff
path: root/src/printf.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2014-10-01 01:52:42 +0000
committerdrh <drh@noemail.net>2014-10-01 01:52:42 +0000
commit595db25b2890e493e978796a439f66925d8a1e3d (patch)
tree36ede06de01a1b4c42b1a2adb9892a772528210a /src/printf.c
parentf1a08ad88ded911534463a7ffa2c298612452f7f (diff)
parentb08cd3f34517bbb7a7cd8c745b2c51fe5bd09082 (diff)
downloadsqlite-595db25b2890e493e978796a439f66925d8a1e3d.tar.gz
sqlite-595db25b2890e493e978796a439f66925d8a1e3d.zip
Merge the latest enhancements from trunk.
FossilOrigin-Name: 2695772c984c215649a16e1e3e18a8048a6a60dd
Diffstat (limited to 'src/printf.c')
-rw-r--r--src/printf.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/printf.c b/src/printf.c
index 6d4b1b4ac..c0b3c70f6 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -1056,6 +1056,69 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
}
#endif
+#ifdef SQLITE_DEBUG
+/*************************************************************************
+** Routines for implementing the "TreeView" display of hierarchical
+** data structures for debugging.
+**
+** The main entry points (coded elsewhere) are:
+** sqlite3TreeViewExpr(0, pExpr, 0);
+** sqlite3TreeViewExprList(0, pList, 0, 0);
+** sqlite3TreeViewSelect(0, pSelect, 0);
+** Insert calls to those routines while debugging in order to display
+** a diagram of Expr, ExprList, and Select objects.
+**
+*/
+/* Add a new subitem to the tree. The moreToFollow flag indicates that this
+** is not the last item in the tree. */
+TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
+ if( p==0 ){
+ p = sqlite3_malloc( sizeof(*p) );
+ if( p==0 ) return 0;
+ memset(p, 0, sizeof(*p));
+ }else{
+ p->iLevel++;
+ }
+ assert( moreToFollow==0 || moreToFollow==1 );
+ if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
+ return p;
+}
+/* Finished with one layer of the tree */
+void sqlite3TreeViewPop(TreeView *p){
+ if( p==0 ) return;
+ p->iLevel--;
+ if( p->iLevel<0 ) sqlite3_free(p);
+}
+/* Generate a single line of output for the tree, with a prefix that contains
+** all the appropriate tree lines */
+void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
+ va_list ap;
+ int i;
+ StrAccum acc;
+ char zBuf[500];
+ sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
+ acc.useMalloc = 0;
+ if( p ){
+ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
+ }
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+ }
+ va_start(ap, zFormat);
+ sqlite3VXPrintf(&acc, 0, zFormat, ap);
+ va_end(ap);
+ if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
+ sqlite3StrAccumFinish(&acc);
+ fprintf(stdout,"%s", zBuf);
+ fflush(stdout);
+}
+/* Shorthand for starting a new tree item that consists of a single label */
+void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
+ p = sqlite3TreeViewPush(p, moreToFollow);
+ sqlite3TreeViewLine(p, "%s", zLabel);
+}
+#endif /* SQLITE_DEBUG */
+
/*
** variable-argument wrapper around sqlite3VXPrintf().
*/