]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Made to build (again).
authorlarrybr <larrybr@noemail.net>
Tue, 9 May 2023 21:20:34 +0000 (21:20 +0000)
committerlarrybr <larrybr@noemail.net>
Tue, 9 May 2023 21:20:34 +0000 (21:20 +0000)
FossilOrigin-Name: 3eb194957c2b21cf017d2909725afdc2a277109c300bc420b8f090653ef986a4

Makefile.in
ext/misc/fileio.c
manifest
manifest.uuid
src/shell.c.in
tool/mkshellc.tcl

index 1a1e18ace83f2a90b305ddd491919fc342d397f9..26aba178579386e01246fb37b86d5da1f2b2ba17 100644 (file)
@@ -1145,26 +1145,26 @@ $(TOP)/ext/misc/basexx.c: $(TOP)/ext/misc/base64.c $(TOP)/ext/misc/base85.c
 
 # Source files that go into making shell.c
 SHELL_SRC = \
-        $(TOP)/src/shell.c.in \
-        $(TOP)/ext/expert/sqlite3expert.c \
-        $(TOP)/ext/expert/sqlite3expert.h \
-        $(TOP)/ext/misc/appendvfs.c \
-        $(TOP)/ext/misc/basexx.c \
-        $(TOP)/ext/misc/completion.c \
-        $(TOP)/ext/misc/decimal.c \
-        $(TOP)/ext/misc/fileio.c \
-        $(TOP)/ext/misc/ieee754.c \
-        $(TOP)/ext/misc/regexp.c \
-        $(TOP)/ext/misc/series.c \
-        $(TOP)/ext/misc/shathree.c \
-        $(TOP)/ext/misc/sqlar.c \
-        $(TOP)/ext/misc/uint.c \
-        $(TOP)/ext/misc/memtrace.c \
-        $(TOP)/src/shext_linkage.h \
-        $(TOP)/src/obj_interfaces.h
-        $(TOP)/ext/recover/dbdata.c \
-        $(TOP)/ext/misc/zipfile.c \
-        $(TOP)/src/test_windirent.c
+  $(TOP)/src/shell.c.in \
+  $(TOP)/ext/expert/sqlite3expert.c \
+  $(TOP)/ext/expert/sqlite3expert.h \
+  $(TOP)/ext/misc/appendvfs.c \
+  $(TOP)/ext/misc/basexx.c \
+  $(TOP)/ext/misc/completion.c \
+  $(TOP)/ext/misc/decimal.c \
+  $(TOP)/ext/misc/fileio.c \
+  $(TOP)/ext/misc/ieee754.c \
+  $(TOP)/ext/misc/regexp.c \
+  $(TOP)/ext/misc/series.c \
+  $(TOP)/ext/misc/shathree.c \
+  $(TOP)/ext/misc/sqlar.c \
+  $(TOP)/ext/misc/uint.c \
+  $(TOP)/ext/misc/memtrace.c \
+  $(TOP)/src/shext_linkage.h \
+  $(TOP)/src/obj_interfaces.h \
+  $(TOP)/ext/recover/dbdata.c \
+  $(TOP)/ext/misc/zipfile.c \
+  $(TOP)/src/test_windirent.c
 
 shell.c:       $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
        $(MKSHELL_TOOL) >shell.c
index 7cdbd5968f5b03f1de6f0081ec53245b66e619a8..d828b84b0f6dde1fb34dcfdab6336969a144de24 100644 (file)
@@ -93,7 +93,7 @@ SQLITE_EXTENSION_INIT1
 #  include <utime.h>
 #  include <sys/time.h>
 #else
-#  include "windows.h"
+#  include <windows.h>
 #  include <io.h>
 #  include <direct.h>
 #  include "test_windirent.h"
index c06480f18ccef6cf8328a7999683a6dd70c56ac2..d05da6de005d5089cc657412bffa9c0b8ce80fb4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
-C WIP,\ssync\swith\strunk\sto\spickup\s22\sweeks\sof\sshell\slibrary\senhancements.
-D 2023-05-08T21:35:07.711
+C Made\sto\sbuild\s(again).
+D 2023-05-09T21:20:34.257
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
-F Makefile.in 07c0feff2b9b50762c3db2413c5d2f67d97c96c4420dbe0e91f7e6dfaeb4bcc6
+F Makefile.in 8e5d01f0df1584356ddb25fbdd3eb03d98a81f1c9f295a6943f8648464bc80f4
 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
 F Makefile.msc 997ff8f34c6e8ec157d2b61e73cf4e1d2d5bcb9ffc6f9af068f4fd4deef0eebf
 F README.md e05bd8fcb45da04ab045c37f79a98654e8aa3b3b8f302cfbba80a0d510df75f7
@@ -290,7 +290,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82
 F ext/misc/decimal.c 57d85fa20a5a74d3b0dfc78ab7934ae6c9f5aa8eed915faa2b5246bec87ddc6d
 F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
 F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe
-F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720
+F ext/misc/fileio.c 37f19acaf22562bae05f530c81c7b24b2c5c091503b115b54ec127958fb5c8bb
 F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
 F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
 F ext/misc/ieee754.c 984d51fe23e956484ec1049df6f5257002e3ab338cabceb39761c2e80ad10bf4
@@ -377,7 +377,7 @@ F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69
 F ext/rbu/sqlite3rbu.c 71a7f0dea3a846ff7c2499dc34a2528f5ddcbe23e2c54dc3cd1fa4d933377c6d
 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055
-F ext/recover/dbdata.c 31d580785cf14eb3c20ed6fbb421a10a66569858f837928e6b326088c38d4c72 w ext/misc/dbdata.c
+F ext/recover/dbdata.c 31d580785cf14eb3c20ed6fbb421a10a66569858f837928e6b326088c38d4c72
 F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf
 F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a
 F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3
@@ -569,7 +569,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 w config.h.in
+F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
 F src/alter.c 482c534877fbb543f8295992cde925df55443febac5db5438d5aaba6f78c4940
 F src/analyze.c a1f3061af16c99f73aed0362160176c31a6452de1b02ada1d68f6839f2a37df0
 F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39
@@ -640,7 +640,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c f9333ef8181192c22662f5cb8d257efc4a2880f9ee4853c6c4616f783d27e1b5
-F src/shell.c.in 352557d6170fb0ab801aaa9d2ad6c3eb9e80bbb47fd49d286bc42379efba5ecb
+F src/shell.c.in 1015edba58449fc685ac69b726d62a7179d10ff39693932cd4e89251f9c54c69
 F src/shext_linkage.h 27dcf7624df05b2a7a6d367834339a6db3636f3035157f641f7db2ec499f8f6d
 F src/sqlite.h.in 27ca1d4b2eda8feee468af5735182390e8fe4696522751eec0136d17323201ad
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -2009,7 +2009,7 @@ F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61
 F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd
 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
 F tool/mkpragmatab.tcl bd07bd59d45d0f3448e123d6937e9811195f9908a51e09d774609883055bfd3d
-F tool/mkshellc.tcl db5df976cdb94518b99551df7af737edaf92f0bc276739b656154980c5054277 x
+F tool/mkshellc.tcl 602b339e31af1a95943b3da1280645bcc16f7c53b861c1e337a06b08fb410cbd x
 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
@@ -2077,8 +2077,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3db119c8d754979ceb16253f1b79b645a5bc68b399406cacc4c50a2a71e84e2d 4ffae48e831eedf8f5e61dc6d38817c0fdccfb2f4f1189d07f9722b9e3a48b5e
-R 71234b6949650e0e0a7eecae7256efe6
+P 00d0d5b10556bcc4ffb8d6083669134a913bc6ae7fcc787af5b1c292923354e8
+R 0a108d83a9607e563592abe617d6b953
 U larrybr
-Z 488bdccb3a6edb132ee652b96b26bff4
+Z d34860c9087d89156fe54998ec77edfc
 # Remove this line to create a well-formed Fossil manifest.
index 150331299d9a7d9cb4b4a5080e79c3a4116945a5..da21de9d8f7b9fcf6b4108b2aa6da02cbc5e1028 100644 (file)
@@ -1 +1 @@
-00d0d5b10556bcc4ffb8d6083669134a913bc6ae7fcc787af5b1c292923354e8
\ No newline at end of file
+3eb194957c2b21cf017d2909725afdc2a277109c300bc420b8f090653ef986a4
\ No newline at end of file
index bcdbdc3e0b6e683f746e8fd144b92908bc1e1402..612a7b6bed4955a96534ccd5e775874a614eacbb 100644 (file)
@@ -537,7 +537,7 @@ static char continuePrompt[PROMPT_LEN_MAX];
 #define SET_MAIN_PROMPT(z) shell_strncpy(mainPrompt,z,PROMPT_LEN_MAX-1)
 #define SET_MORE_PROMPT(z) shell_strncpy(continuePrompt,z,PROMPT_LEN_MAX-1);
 /* Prompts as ready to be used by shell's input function */
-static Prompts shellPrompts = { mainPrompt, continuePrompt, 0 };
+static Prompts shellPrompts = { mainPrompt, continuePrompt };
 
 #ifdef SQLITE_OMIT_DYNAPROMPT
 /*
@@ -607,7 +607,7 @@ static void dynamicContinuePrompt(void){
   if( dynPrompt.zScannerAwaits ){
     size_t ncp = strlen(continuePrompt);
     size_t ndp = strlen(dynPrompt.zScannerAwaits);
-    if( ndp > ncp-3 ) goto plain continuation;
+    if( ndp > ncp-3 ) goto plain_continuation;
       strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
       while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
       shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
@@ -1116,7 +1116,7 @@ static char *one_input_line(InSource *pInSrc, char *zPrior,
   if( !INSOURCE_IS_INTERACTIVE(pInSrc) ){
     return local_getline(zPrior, pInSrc);
   }else{
-    static Prompts cueDefault = { "$ ","> ", 0 };
+    static Prompts cueDefault = { "$ ","> " };
     const char *zPrompt;
     char *zResult;
     if( pCue==0 ) pCue = &cueDefault;
@@ -1470,6 +1470,8 @@ static void shellAddSchemaName(
 ** code, we need to override some macros to make the included program code
 ** work here in the middle of this regular program.
 */
+#undef SQLITE_EXTENSION_INIT1
+#undef SQLITE_EXTENSION_INIT2
 #define SQLITE_EXTENSION_INIT1
 #define SQLITE_EXTENSION_INIT2(X) (void)(X)
 
@@ -1479,9 +1481,6 @@ INCLUDE test_windirent.c
 #define dirent DIRENT
 #endif
 INCLUDE ../ext/misc/shathree.c
-INCLUDE ../ext/misc/fileio.c
-INCLUDE ../ext/misc/completion.c
-INCLUDE ../ext/misc/appendvfs.c
 INCLUDE ../ext/misc/memtrace.c
 INCLUDE ../ext/misc/uint.c
 INCLUDE ../ext/misc/decimal.c
@@ -5062,7 +5061,7 @@ static int shell_exec(
 
       /* print loop-counters if required */
       if( psx && psi->scanstatsOn ){
-        display_scanstats(psi);
+        display_scanstats(db, psi);
       }
 
       /* Finalize the statement just executed. If this fails, save a
@@ -5736,7 +5735,7 @@ static void open_db(ShellExState *psx, int openFlags){
 
     /* Reflect the use or absence of --unsafe-testing invocation. */
     {
-      int testmode_on = ShellHasFlag(psi,SHFLG_TestingMode);
+      int testmode_on = ShellHasFlag(psx,SHFLG_TestingMode);
       sqlite3_db_config(globalDb, SQLITE_DBCONFIG_TRUSTED_SCHEMA,testmode_on,0);
       sqlite3_db_config(globalDb, SQLITE_DBCONFIG_DEFENSIVE, !testmode_on,0);
     }
@@ -5746,8 +5745,8 @@ static void open_db(ShellExState *psx, int openFlags){
     sqlite3_shathree_init(globalDb, 0, 0);
     sqlite3_uint_init(globalDb, 0, 0);
     sqlite3_decimal_init(globalDb, 0, 0);
-    sqlite3_base64_init(p->db, 0, 0);
-    sqlite3_base85_init(p->db, 0, 0);
+    sqlite3_base64_init(globalDb, 0, 0);
+    sqlite3_base85_init(globalDb, 0, 0);
     sqlite3_regexp_init(globalDb, 0, 0);
     sqlite3_ieee_init(globalDb, 0, 0);
     sqlite3_series_init(globalDb, 0, 0);
@@ -7325,7 +7324,7 @@ static DotCmdRC arParseCommand(
   }
   if( pAr->eCmd==0 ){
     utf8_printf(stderr, "Required argument missing.  Usage:\n");
-    return arUsage(stderr);
+    return arUsage(stderr,pAr);
   }
   return SQLITE_OK;
 }
@@ -7832,69 +7831,6 @@ static int recoverSqlCb(void *pCtx, const char *zSql){
   return SQLITE_OK;
 }
 
-/*
-** This function is called to recover data from the database. A script
-** to construct a new database containing all recovered data is output
-** on stream pState->out.
-*/
-static int recoverDatabaseCmd(ShellInState *pState, int nArg, char **azArg){
-  int rc = SQLITE_OK;
-  const char *zRecoveryDb = "";   /* Name of "recovery" database.  Debug only */
-  const char *zLAF = "lost_and_found";
-  int bFreelist = 1;              /* 0 if --ignore-freelist is specified */
-  int bRowids = 1;                /* 0 if --no-rowids */
-  sqlite3_recover *p = 0;
-  int i = 0;
-
-  for(i=1; i<nArg; i++){
-    char *z = azArg[i];
-    int n;
-    if( z[0]=='-' && z[1]=='-' ) z++;
-    n = strlen30(z);
-    if( n<=17 && memcmp("-ignore-freelist", z, n)==0 ){
-      bFreelist = 0;
-    }else
-    if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
-      /* This option determines the name of the ATTACH-ed database used
-      ** internally by the recovery extension.  The default is "" which
-      ** means to use a temporary database that is automatically deleted
-      ** when closed.  This option is undocumented and might disappear at
-      ** any moment. */
-      i++;
-      zRecoveryDb = azArg[i];
-    }else
-    if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
-      i++;
-      zLAF = azArg[i];
-    }else
-    if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
-      bRowids = 0;
-    }
-    else{
-      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
-      showHelp(pState->out, azArg[0]);
-      return 1;
-    }
-  }
-
-  p = sqlite3_recover_init_sql(
-      pState->db, "main", recoverSqlCb, (void*)pState
-  );
-
-  sqlite3_recover_config(p, 789, (void*)zRecoveryDb);  /* Debug use only */
-  sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
-  sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
-  sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
-
-  sqlite3_recover_run(p);
-  if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
-    const char *zErr = sqlite3_recover_errmsg(p);
-    int errCode = sqlite3_recover_errcode(p);
-    raw_printf(stderr, "sql error: %s (%d)\n", zErr, errCode);
-  }
-  rc = sqlite3_recover_finish(p);
-  return rc;
-}
 #endif /* SQLITE_SHELL_HAVE_RECOVER */
 
 #ifndef SQLITE_SHELL_FIDDLE
@@ -9395,26 +9331,24 @@ DISPATCHABLE_COMMAND( check 3 0 0 ){
   ** azArg[1].  If there are differences, report an error and exit.
   */
   char *zRes = 0;
-  int rc = 0;
   DotCmdRC rv = DCR_Ok;
   output_reset(ISS(p));
   if( nArg!=2 ){
     return DCR_ArgWrong;
   }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
-    *pzErr = shellMPrintf(&rc, "Error: cannot read 'testcase-out.txt'\n");
+    *pzErr = smprintf("Error: cannot read 'testcase-out.txt'\n");
     rv = DCR_Return;
   }else if( testcase_glob(azArg[1],zRes)==0 ){
     *pzErr =
-      shellMPrintf(&rc,
-                   "testcase-%s FAILED\n Expected: [%s]\n      Got: [%s]\n",
-                   ISS(p)->zTestcase, azArg[1], zRes);
+      smprintf("testcase-%s FAILED\n Expected: [%s]\n      Got: [%s]\n",
+               ISS(p)->zTestcase, azArg[1], zRes);
     rv = DCR_Error;
   }else{
     utf8_printf(STD_OUT, "testcase-%s ok\n", ISS(p)->zTestcase);
     ISS(p)->nCheck++;
   }
   sqlite3_free(zRes);
-  return (rc==SQLITE_NOMEM)? DCR_Abort : rv;
+  return (zRes==0)? DCR_Abort : rv;
 }
 DISPATCHABLE_COMMAND( clone ? 2 2 ){
   if( ISS(p)->bSafeMode ) return DCR_AbortError;
@@ -10621,6 +10555,8 @@ COLLECT_HELP_TEXT[
   ".lint OPTIONS            Report potential schema issues.",
   "     Options:",
   "        fkey-indexes     Find missing foreign key indexes",
+];
+COLLECT_HELP_TEXT[
 #if !defined(SQLITE_SHELL_FIDDLE)
   ".log FILE|on|off         Turn logging on or off.  FILE can be stderr/stdout",
 #else
@@ -12138,320 +12074,65 @@ COLLECT_HELP_TEXT[
 ** on stream pState->out.
 */
 DISPATCHABLE_COMMAND( recover ? 1 7 ){
+  int rc = SQLITE_OK;
+  const char *zRecoveryDb = "";   /* Name of "recovery" database. Debug only */
+  const char *zLAF = "lost_and_found";
+  int bFreelist = 1;              /* 0 if --ignore-freelist is specified */
+  int bRowids = 1;                /* 0 if --no-rowids */
+  sqlite3_recover *pr = 0;
+  int i = 0;
   FILE *out = ISS(p)->out;
   sqlite3 *db;
-  int rc = SQLITE_OK;
-  sqlite3_stmt *pLoop = 0;        /* Loop through all root pages */
-  sqlite3_stmt *pPages = 0;       /* Loop through all pages in a group */
-  sqlite3_stmt *pCells = 0;       /* Loop through all cells in a page */
-  const char *zRecoveryDb = "";   /* Name of "recovery" database */
-  const char *zLostAndFound = "lost_and_found";
-  int i;
-  int nOrphan = -1;
-  RecoverTable *pOrphan = 0;
 
   open_db(p, 0);
   db = DBX(p);
 
-  int bFreelist = 1;              /* 0 if --freelist-corrupt is specified */
-  int bRowids = 1;                /* 0 if --no-rowids */
   for(i=1; i<nArg; i++){
     char *z = azArg[i];
     int n;
     if( z[0]=='-' && z[1]=='-' ) z++;
     n = strlen30(z);
-    if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
+    if( n<=17 && memcmp("-ignore-freelist", z, n)==0 ){
       bFreelist = 0;
     }else
     if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
+      /* This option determines the name of the ATTACH-ed database used
+      ** internally by the recovery extension.  The default is "" which
+      ** means to use a temporary database that is automatically deleted
+      ** when closed.  This option is undocumented and might disappear at
+      ** any moment. */
       i++;
       zRecoveryDb = azArg[i];
     }else
     if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
       i++;
-      zLostAndFound = azArg[i];
+      zLAF = azArg[i];
     }else
     if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
       bRowids = 0;
     }
     else{
-      *pzErr = smprintf("unexpected option: %s\n", azArg[i]);
-      showHelp(out, azArg[0], p);
-      return DCR_CmdErred;
-    }
-  }
-
-  shellExecPrintf(db, &rc,
-    /* Attach an in-memory database named 'recovery'. Create an indexed
-    ** cache of the sqlite_dbptr virtual table. */
-    "PRAGMA writable_schema = on;"
-    "ATTACH %Q AS recovery;"
-    "DROP TABLE IF EXISTS recovery.dbptr;"
-    "DROP TABLE IF EXISTS recovery.freelist;"
-    "DROP TABLE IF EXISTS recovery.map;"
-    "DROP TABLE IF EXISTS recovery.schema;"
-    "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
-  );
-
-  if( bFreelist ){
-    shellExec(db, &rc,
-      "WITH trunk(pgno) AS ("
-      "  SELECT shell_int32("
-      "      (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
-      "      WHERE x>0"
-      "    UNION"
-      "  SELECT shell_int32("
-      "      (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
-      "      FROM trunk WHERE x>0"
-      "),"
-      "freelist(data, n, freepgno) AS ("
-      "  SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
-      "      FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
-      "    UNION ALL"
-      "  SELECT data, n-1, shell_int32(data, 2+n) "
-      "      FROM freelist WHERE n>=0"
-      ")"
-      "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
-    );
-  }
-
-  /* If this is an auto-vacuum database, add all pointer-map pages to
-  ** the freelist table. Do this regardless of whether or not
-  ** --freelist-corrupt was specified.  */
-  shellExec(db, &rc,
-    "WITH ptrmap(pgno) AS ("
-    "  SELECT 2 WHERE shell_int32("
-    "    (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
-    "  )"
-    "    UNION ALL "
-    "  SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
-    "  FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
-    ")"
-    "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
-  );
-
-  shellExec(db, &rc,
-    "CREATE TABLE recovery.dbptr("
-    "      pgno, child, PRIMARY KEY(child, pgno)"
-    ") WITHOUT ROWID;"
-    "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
-    "    SELECT * FROM sqlite_dbptr"
-    "      WHERE pgno NOT IN freelist AND child NOT IN freelist;"
-
-    /* Delete any pointer to page 1. This ensures that page 1 is considered
-    ** a root page, regardless of how corrupt the db is. */
-    "DELETE FROM recovery.dbptr WHERE child = 1;"
-
-    /* Delete all pointers to any pages that have more than one pointer
-    ** to them. Such pages will be treated as root pages when recovering
-    ** data.  */
-    "DELETE FROM recovery.dbptr WHERE child IN ("
-    "  SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
-    ");"
-
-    /* Create the "map" table that will (eventually) contain instructions
-    ** for dealing with each page in the db that contains one or more
-    ** records. */
-    "CREATE TABLE recovery.map("
-      "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
-    ");"
-
-    /* Populate table [map]. If there are circular loops of pages in the
-    ** database, the following adds all pages in such a loop to the map
-    ** as individual root pages. This could be handled better.  */
-    "WITH pages(i, maxlen) AS ("
-    "  SELECT page_count, ("
-    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
-    "  ) FROM pragma_page_count WHERE page_count>0"
-    "    UNION ALL"
-    "  SELECT i-1, ("
-    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
-    "  ) FROM pages WHERE i>=2"
-    ")"
-    "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
-    "  SELECT i, maxlen, NULL, ("
-    "    WITH p(orig, pgno, parent) AS ("
-    "      SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
-    "        UNION "
-    "      SELECT i, p.parent, "
-    "        (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
-    "    )"
-    "    SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
-    ") "
-    "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
-    "UPDATE recovery.map AS o SET intkey = ("
-    "  SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
-    ");"
-
-    /* Extract data from page 1 and any linked pages into table
-    ** recovery.schema. With the same schema as an sqlite_schema table.  */
-    "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
-    "INSERT INTO recovery.schema SELECT "
-    "  max(CASE WHEN field=0 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=1 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=2 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=3 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=4 THEN value ELSE NULL END)"
-    "FROM sqlite_dbdata WHERE pgno IN ("
-    "  SELECT pgno FROM recovery.map WHERE root=1"
-    ")"
-    "GROUP BY pgno, cell;"
-    "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
-  );
-
-  /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
-  ** CREATE TABLE statements that extracted from the existing schema.  */
-  if( rc==SQLITE_OK ){
-    sqlite3_stmt *pStmt = 0;
-    /* ".recover" might output content in an order which causes immediate
-    ** foreign key constraints to be violated. So disable foreign-key
-    ** constraint enforcement to prevent problems when running the output
-    ** script. */
-    raw_printf(out, "PRAGMA foreign_keys=OFF;\n");
-    raw_printf(out, "BEGIN;\n");
-    raw_printf(out, "PRAGMA writable_schema = on;\n");
-    shellPrepare(db, &rc,
-        "SELECT sql FROM recovery.schema "
-        "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
-    );
-    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
-      const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
-      raw_printf(out, "CREATE TABLE IF NOT EXISTS %s;\n", &zCreateTable[12]);
+      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
+      showHelp(stderr, azArg[0], p);
+      return DCR_Error;
     }
-    shellFinalize(&rc, pStmt);
-  }
-
-  /* Figure out if an orphan table will be required. And if so, how many
-  ** user columns it should contain */
-  shellPrepare(db, &rc,
-      "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
-      , &pLoop
-  );
-  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
-    nOrphan = sqlite3_column_int(pLoop, 0);
   }
-  shellFinalize(&rc, pLoop);
-  pLoop = 0;
-
-  shellPrepare(db, &rc,
-      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
-  );
 
-  shellPrepare(db, &rc,
-      "SELECT max(field), group_concat(shell_escape_crnl(quote"
-      "(case when (? AND field<0) then NULL else value end)"
-      "), ', ')"
-      ", min(field) "
-      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
-      "GROUP BY cell", &pCells
-  );
-
-  /* Loop through each root page. */
-  shellPrepare(db, &rc,
-      "SELECT root, intkey, max(maxlen) FROM recovery.map"
-      " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
-      "  SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
-      ")", &pLoop
-  );
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
-    int iRoot = sqlite3_column_int(pLoop, 0);
-    int bIntkey = sqlite3_column_int(pLoop, 1);
-    int nCol = sqlite3_column_int(pLoop, 2);
-    int bNoop = 0;
-    RecoverTable *pTab;
-
-    assert( bIntkey==0 || bIntkey==1 );
-    pTab = recoverFindTable(db, &rc, iRoot, bIntkey, nCol, &bNoop);
-    if( bNoop || rc ) continue;
-    if( pTab==0 ){
-      if( pOrphan==0 ){
-        pOrphan = recoverOrphanTable(db, out, &rc, zLostAndFound, nOrphan);
-      }
-      pTab = pOrphan;
-      if( pTab==0 ) break;
-    }
-
-    if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
-      raw_printf(out, "DELETE FROM sqlite_sequence;\n");
-    }
-    sqlite3_bind_int(pPages, 1, iRoot);
-    if( bRowids==0 && pTab->iPk<0 ){
-      sqlite3_bind_int(pCells, 1, 1);
-    }else{
-      sqlite3_bind_int(pCells, 1, 0);
-    }
-    sqlite3_bind_int(pCells, 3, pTab->iPk);
-
-    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
-      int iPgno = sqlite3_column_int(pPages, 0);
-      sqlite3_bind_int(pCells, 2, iPgno);
-      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
-        int nField = sqlite3_column_int(pCells, 0);
-        int iMin = sqlite3_column_int(pCells, 2);
-        const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
-
-        RecoverTable *pTab2 = pTab;
-        if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
-          if( pOrphan==0 ){
-            pOrphan = recoverOrphanTable(db, out, &rc, zLostAndFound, nOrphan);
-          }
-          pTab2 = pOrphan;
-          if( pTab2==0 ) break;
-        }
+  pr = sqlite3_recover_init_sql(db, "main", recoverSqlCb, (void*)p);
 
-        nField = nField+1;
-        if( pTab2==pOrphan ){
-          raw_printf(out,
-              "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
-              pTab2->zQuoted, iRoot, iPgno, nField,
-              iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
-          );
-        }else{
-          raw_printf(out, "INSERT INTO %s(%s) VALUES( %s );\n",
-              pTab2->zQuoted, pTab2->azlCol[nField], zVal
-          );
-        }
-      }
-      shellReset(&rc, pCells);
-    }
-    shellReset(&rc, pPages);
-    if( pTab!=pOrphan ) recoverFreeTable(pTab);
-  }
-  shellFinalize(&rc, pLoop);
-  shellFinalize(&rc, pPages);
-  shellFinalize(&rc, pCells);
-  recoverFreeTable(pOrphan);
+  sqlite3_recover_config(pr, 789, (void*)zRecoveryDb);  /* Debug use only */
+  sqlite3_recover_config(pr, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
+  sqlite3_recover_config(pr, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
+  sqlite3_recover_config(pr, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
 
-  /* The rest of the schema */
-  if( rc==SQLITE_OK ){
-    sqlite3_stmt *pStmt = 0;
-    shellPrepare(db, &rc,
-        "SELECT sql, name FROM recovery.schema "
-        "WHERE sql NOT LIKE 'create table%'", &pStmt
-    );
-    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
-      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
-      if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
-        const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
-        char *zPrint = shellMPrintf(&rc,
-          "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
-          zName, zName, zSql
-        );
-        raw_printf(out, "%s;\n", zPrint);
-        sqlite3_free(zPrint);
-      }else{
-        raw_printf(out, "%s;\n", zSql);
-      }
-    }
-    shellFinalize(&rc, pStmt);
-  }
-
-  if( rc==SQLITE_OK ){
-    raw_printf(out, "PRAGMA writable_schema = off;\n");
-    raw_printf(out, "COMMIT;\n");
+  sqlite3_recover_run(pr);
+  if( sqlite3_recover_errcode(pr)!=SQLITE_OK ){
+    const char *zErr = sqlite3_recover_errmsg(pr);
+    int errCode = sqlite3_recover_errcode(pr);
+    raw_printf(stderr, "sql error: %s (%d)\n", zErr, errCode);
   }
-  sqlite3_exec(db, "DETACH recovery", 0, 0, 0);
-  return rc;
+  rc = sqlite3_recover_finish(pr);
+  return rc? DCR_Error : DCR_Ok;
 }
 
 DISPATCHABLE_COMMAND( restore ? 2 3 ){
@@ -12517,15 +12198,14 @@ COLLECT_HELP_TEXT[
   "      --nosys              Omit objects whose names start with \"sqlite_\"",
 ];
 DISPATCHABLE_COMMAND( scanstats ? 2 2 ){
-  ISS(p)->scanstatsOn = (u8)booleanValue(azArg[1]);
   if( cli_strcmp(azArg[1], "est")==0 ){
-    p->scanstatsOn = 2;
+    ISS(p)->scanstatsOn = 2;
   }else{
-    p->scanstatsOn = (u8)booleanValue(azArg[1]);
+    ISS(p)->scanstatsOn = (u8)booleanValue(azArg[1]);
   }
   open_db(p, 0);
-  sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS,
-                    p->scanstatsOn, (int*)0);
+  sqlite3_db_config(DBX(p), SQLITE_DBCONFIG_STMT_SCANSTATUS,
+                    ISS(p)->scanstatsOn, (int*)0);
 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
   raw_printf(STD_ERR, "Warning: .scanstats not available in this build.\n");
 #endif
@@ -12705,11 +12385,6 @@ COLLECT_HELP_TEXT[
   "      --sha3-512            Use the sha3-512 algorithm",
   "    Any other argument is a LIKE pattern for tables to hash",
 ];
-DISPATCHABLE_COMMAND( selecttrace ? 1 0 ){
-  unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
-  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
-  return DCR_Ok;
-}
 DISPATCHABLE_COMMAND( separator ? 2 3 ){
   if( nArg>=2 ){
     sqlite3_snprintf(sizeof(ISS(p)->colSeparator), ISS(p)->colSeparator,
@@ -13060,8 +12735,8 @@ DISPATCHABLE_COMMAND( sha3sum 4 1 1 ){
         "' OR ') as query, tname from tabcols group by tname)"
         , zRevText);
     shell_check_oom(zRevText);
-    if( bDebug ) utf8_printf(p->out, "%s\n", zRevText);
-    lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
+    if( bDebug ) utf8_printf(ISS(p)->out, "%s\n", zRevText);
+    lrc = sqlite3_prepare_v2(DBX(p), zRevText, -1, &pStmt, 0);
     if( lrc!=SQLITE_OK ){
       sqlite3_free(zRevText);
       return DCR_Error;
@@ -13071,8 +12746,8 @@ DISPATCHABLE_COMMAND( sha3sum 4 1 1 ){
     if( lrc ){
       const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
       sqlite3_stmt *pCheckStmt;
-      lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
-      if( bDebug ) utf8_printf(p->out, "%s\n", zGenQuery);
+      lrc = sqlite3_prepare_v2(DBX(p), zGenQuery, -1, &pCheckStmt, 0);
+      if( bDebug ) utf8_printf(ISS(p)->out, "%s\n", zGenQuery);
       if( SQLITE_OK!=lrc ){
         sqlite3_finalize(pStmt);
         sqlite3_free(zRevText);
@@ -14037,7 +13712,7 @@ DISPATCHABLE_COMMAND( user ? 0 0 ){
     rc = sqlite3_user_authenticate(DBX(p), azArg[2], azArg[3],
                                    strlen30(azArg[3]));
     if( rc ){
-      *pzErr = shellMPrintf(0,"Authentication failed for user %s\n", azArg[2]);
+      *pzErr = smprintf(0,"Authentication failed for user %s\n", azArg[2]);
       return DCR_Error;
     }
   }else if( cli_strcmp(azArg[1],"add")==0 ){
@@ -14047,7 +13722,7 @@ DISPATCHABLE_COMMAND( user ? 0 0 ){
     rc = sqlite3_user_add(DBX(p), azArg[2], azArg[3], strlen30(azArg[3]),
                           booleanValue(azArg[4]));
     if( rc ){
-      *pzErr = shellMPrintf(0,"User-Add failed: %d\n", rc);
+      *pzErr = smprintf(0,"User-Add failed: %d\n", rc);
       return DCR_Error;
     }
   }else if( cli_strcmp(azArg[1],"edit")==0 ){
@@ -14057,7 +13732,7 @@ DISPATCHABLE_COMMAND( user ? 0 0 ){
     rc = sqlite3_user_change(DBX(p), azArg[2], azArg[3], strlen30(azArg[3]),
                              booleanValue(azArg[4]));
     if( rc ){
-      *pzErr = shellMPrintf(0,"User-Edit failed: %d\n", rc);
+      *pzErr = smprintf(0,"User-Edit failed: %d\n", rc);
       return DCR_Error;
     }
   }else if( cli_strcmp(azArg[1],"delete")==0 ){
@@ -14066,7 +13741,7 @@ DISPATCHABLE_COMMAND( user ? 0 0 ){
     }
     rc = sqlite3_user_delete(DBX(p), azArg[2]);
     if( rc ){
-      *pzErr = shellMPrintf(0,"User-Delete failed: %d\n", rc);
+      *pzErr = smprintf(0,"User-Delete failed: %d\n", rc);
       return DCR_Error;
     }
   }else{
@@ -15469,10 +15144,6 @@ static int runOneSqlLine(ShellExState *psx, char *zSql,
   return 0;
 }
 
-static void echo_group_input(ShellState *p, const char *zDo){
-  if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n", zDo);
-}
-
 #if SHELL_EXTENDED_PARSING
 /* Resumable line classsifier for dot-commands
 **
@@ -15575,7 +15246,7 @@ static void dot_command_scan(char *zCmd, DCmd_ScanState *pScanState,
   *pScanState = ss;
 }
 #else
-# define dot_command_scan(x,y)
+# define dot_command_scan(x,y,z)
 #endif
 
 /* Utility functions for process_input. */
@@ -15611,7 +15282,7 @@ static int line_join_done(DCmd_ScanState dcss, char *zLine,
 ** In/out parameters pz and pna reference the buffer and its size.
 ** The buffer must eventually be sqlite3_free()'ed by the caller.
 */
-static void grow_line_buffer(char **pz, int *pna, int ncNeed){
+static void grow_line_buffer(char **pz, i64 *pna, int ncNeed){
 
   if( ncNeed > *pna ){
     *pna += *pna + (*pna>>1) + 100;
@@ -15699,7 +15370,7 @@ static DotCmdRC process_input(ShellInState *psi){
       Incoming, Runnable, Dumpable, Erroneous, Ignore
     } disposition = Incoming;
     char **pzLineUse = &zLineInput;   /* ref line to be processed */
-    int *pncLineUse = &ncLineIn;      /* ref that line's char count */
+    i64 *pncLineUse = &ncLineIn;      /* ref that line's char count */
     int iStartline = 0;               /* starting line number of group */
 
     fflush(psi->out);
@@ -16597,7 +16268,7 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){
     }else if( cli_strcmp(z,"-quiet")==0 ){
       bQuiet = (int)integerValue(cmdline_option_value(argc,argv,++i));
     }else if( cli_strcmp(z,"-unsafe-testing")==0 ){
-      ShellSetFlag(&data,SHFLG_TestingMode);
+      data.shellFlgs |= SHFLG_TestingMode;
     }else if( cli_strcmp(z,"-safe")==0 ){
       /* catch this on the second pass (Unsafe is fine on invocation.) */
     }
index 24d54d0cb0f0c39cca96996c173091efbbe8ab87..b6157e82a05d69cf8c12b044ec6a4e1af5c000bd 100755 (executable)
@@ -177,9 +177,10 @@ if {$runMode eq "normal"} {
   set ::outStrm stdout
 }
 
-# Given a path relative to <project>/src, return its full pathname.
-proc project_path {relPath} {
-  return "$::topDir/src/$relPath"
+# Given an include path relative to some file path from within which the
+# file is to be included, return includee's full pathname.
+proc project_path {relPath fromPath} {
+  return [file normalize [file join [file dirname $fromPath] $relPath]]
 }
 
 if {$::lineTags >= 3} {
@@ -478,7 +479,7 @@ proc INCLUDE {inSrc tailCaptureIncType ostrm} {
   if {$it ne ""} {
     if {[info exists ::incTypes($it)]} {
       set rfpath $::incTypes($it)
-      if {![file exists [project_path $rfpath]]} {
+      if {![file exists [project_path $rfpath $srcFile]]} {
         set saySkip "/* INCLUDE($it), of missing \"$rfpath\" skipped. */"
       }
     } else {
@@ -488,7 +489,7 @@ proc INCLUDE {inSrc tailCaptureIncType ostrm} {
   if {$saySkip ne ""} {
     emit_sync [list $saySkip] $ostrm $srcPrecLines $srcFile
   } else {
-    process_file [project_path $rfpath] $ostrm
+    process_file [project_path $rfpath $srcFile] $ostrm
     incr srcPrecLines
     emit_sync {} $ostrm $srcPrecLines $srcFile
   }
@@ -754,20 +755,21 @@ proc transform_line {lineVar nesting} {
   # other sources, to the detriment of clarity and robustness. Presently,
   # topLevelGen 1 is used for shell.c and other C source(s), and 0 is used
   # for generated .h files.
-  if {[regexp {^# *include } $line]} {
+  if {[regexp {^ *# *include } $line]} {
     if {$::topLevelGen} {
       set noInc [regexp {^# *include "test_windirent.h"} $line]
-      incr noInc [regexp {^#include "sqlite.*"} $line]
+      set hf "test_windirent.h"
+      incr noInc [regexp {^ *# *include "(sqlite3(ext)?\.h)"} $line _ hf]
       if {$noInc > 0} {
         set line "/* $line */"
         return 1
       }
     } else {
-      set pass [regexp {^# *include "sqlite3.h"} $line]
+      set pass [regexp {^ *# *include "(sqlite3(ext)?\.h)"} $line _ hf]
       if {$pass} {
-        set block [info exists ::includesDone(sqlite3.h)]
+       set block [info exists ::includesDone($hf)]
         if {!$block} {
-          set ::includesDone(sqlite3.h) 1
+          set ::includesDone($hf) 1
         } else {
           set line "/* $line */"
         }
@@ -775,7 +777,7 @@ proc transform_line {lineVar nesting} {
       }
     }
   }
-  if {[regexp {^#include "([\w\.]+)"} $line _ incRelPath]} {
+  if {[regexp {^ *# *include "([\w\.]+)"} $line _ incRelPath]} {
     set fromPath [lindex $::incFileStack end]
     set incPath [file join [file dirname $fromPath] $incRelPath]
     set inTree [file exists $incPath]