--- shell_3.3.8_org.c	2007-01-04 09:19:03.000000000 +0100
+++ shell.c	2007-01-04 09:43:52.000000000 +0100
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <assert.h>
+#include <time.h>
 #include "sqlite3.h"
 #include <ctype.h>
 
@@ -85,6 +86,8 @@
 static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
 
+static int profilingMode = 0;
+static clock_t timerstart = 0;
 
 /*
 ** Determines if a string is a number of not.
@@ -781,6 +784,7 @@
   ".nullvalue STRING      Print STRING in place of NULL values\n"
   ".output FILENAME       Send output to FILENAME\n"
   ".output stdout         Send output to the screen\n"
+  ".profile ON|OFF        Turn profiling on or off\n"
   ".prompt MAIN CONTINUE  Replace the standard prompts\n"
   ".quit                  Exit this program\n"
   ".read FILENAME         Execute SQL in FILENAME\n"
@@ -789,6 +793,7 @@
   ".show                  Show the current values for various settings\n"
   ".tables ?PATTERN?      List names of tables matching a LIKE pattern\n"
   ".timeout MS            Try opening locked tables for MS milliseconds\n"
+  ".timer start|show      Measure elapsed CPU time\n"
   ".width NUM NUM ...     Set column widths for \"column\" mode\n"
 ;
 
@@ -1241,6 +1246,29 @@
     }
   }else
 
+  if( c=='p' && strncmp(azArg[0], "profile", n)==0 && nArg>1 ){
+    int j;
+    char *z = azArg[1];
+    int val = atoi(azArg[1]);
+    for(j=0; z[j]; j++){
+      z[j] = tolower((unsigned char)z[j]);
+    }
+    if( strcmp(z,"on")==0 ){
+      val = 1;
+    }else if( strcmp(z,"yes")==0 ){
+      val = 1;
+    }
+    profilingMode = val;
+    if( profilingMode ){
+      p->out = fopen("/dev/null", "wb");
+      strcpy(p->outfile, "/dev/null");
+    } else {
+      p->out = stdout;
+      strcpy(p->outfile, "stdout");
+    }
+    
+  }else
+
   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
     if( nArg >= 2) {
       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
@@ -1412,6 +1440,18 @@
     sqlite3_busy_timeout(p->db, atoi(azArg[1]));
   }else
 
+  if( c=='t' && strncmp(azArg[0], "timer", n)==0 && nArg>=2 ){
+    static clock_t timerstart = 0;
+    time_t  now = time( NULL );
+    if( strcmp(azArg[1],"start")==0 ){
+      timerstart = clock();
+      printf("Start time: %13s %s", "", ctime( &now ) );
+    }else if (strcmp(azArg[1],"show")==0 ){
+      clock_t tmp = clock();
+      printf("Exec time:  %10.3lf s. %s", (1.0 * tmp - timerstart) / CLOCKS_PER_SEC, ctime( &now ) );
+    }
+  }else
+
   if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
     int j;
     assert( nArg<=ArraySize(azArg) );
@@ -1462,6 +1502,20 @@
 }
 
 /*
+** Scan string and return position of first line feed.
+** z[] is N characters long.
+** Return -1 if nothing is found.
+*/
+static int find_first_linefeed(const char *z, int N){
+  int pos = 0;
+  while (pos < N && *z && *z!='\n'){ 
+    pos++;
+    z++;
+  }
+  return (pos != N) ? pos : -1;  
+}
+
+/*
 ** Return TRUE if the line typed in is an SQL command terminator other
 ** than a semi-colon.  The SQL Server style "go" command is understood
 ** as is the Oracle "/".
@@ -1532,6 +1586,8 @@
     if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
       p->cnt = 0;
       open_db(p);
+      if( profilingMode )
+        timerstart = clock();
       rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
       if( rc || zErrMsg ){
         /* if( in!=0 && !p->echoOn ) printf("%s\n",zSql); */
@@ -1542,6 +1598,23 @@
         }else{
           printf("SQL error: %s\n", sqlite3_errmsg(p->db));
         }
+      }else if( profilingMode ){
+        float timeElapsed = (1.0 * clock() - timerstart) / CLOCKS_PER_SEC;
+        int zSqlLen = strlen(zSql);
+        int cutpos = find_first_linefeed(zSql, zSqlLen);
+        if( cutpos == -1 && zSqlLen > 45 ){
+          cutpos = 1;
+        }else if( cutpos > -1 ){
+          zSql[cutpos] = 0;
+          cutpos = 1;
+        }else{
+          cutpos = 0;
+        }
+        if( cutpos ){
+          printf("Exec time  %-42.42s...  :  %5.3lf s.\n", zSql, timeElapsed);
+        }else{
+          printf("Exec time  %-45.45s  :  %5.3lf s.\n", zSql, timeElapsed);
+        }
       }
       free(zSql);
       zSql = 0;
