From 317269e6c1ade627329f3d4e6dca38dd231310e4 Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 9 May 2023 21:20:34 +0000 Subject: [PATCH] Made to build (again). FossilOrigin-Name: 3eb194957c2b21cf017d2909725afdc2a277109c300bc420b8f090653ef986a4 --- Makefile.in | 40 ++-- ext/misc/fileio.c | 2 +- manifest | 22 +-- manifest.uuid | 2 +- src/shell.c.in | 451 +++++++--------------------------------------- tool/mkshellc.tcl | 24 +-- 6 files changed, 107 insertions(+), 434 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1a1e18ace8..26aba17857 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index 7cdbd5968f..d828b84b0f 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -93,7 +93,7 @@ SQLITE_EXTENSION_INIT1 # include # include #else -# include "windows.h" +# include # include # include # include "test_windirent.h" diff --git a/manifest b/manifest index c06480f18c..d05da6de00 100644 --- 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. diff --git a/manifest.uuid b/manifest.uuid index 150331299d..da21de9d8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00d0d5b10556bcc4ffb8d6083669134a913bc6ae7fcc787af5b1c292923354e8 \ No newline at end of file +3eb194957c2b21cf017d2909725afdc2a277109c300bc420b8f090653ef986a4 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index bcdbdc3e0b..612a7b6bed 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -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; iout, 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; i0" - " 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.) */ } diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 24d54d0cb0..b6157e82a0 100755 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -177,9 +177,10 @@ if {$runMode eq "normal"} { set ::outStrm stdout } -# Given a path relative to /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] -- 2.47.3