From 9ff8a73ba443a7ede6285c4c3311628c2e0f72a0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 5 Nov 2025 12:37:42 +0000 Subject: [PATCH] New build product "tclsqlite-ex.c" is the tclsqlite.c file with QRF added. This is now used whereever tclsqlite.c was used. Hence QRF is now in the testfixture and in the tclextension. The sqlite3 method is "format". That method is currently just a non-functional stub. FossilOrigin-Name: e08d21fe1365176f268f1dcca4048fb5ff043356e5817c8622b4ed9a1a5a58cf --- Makefile.msc | 30 ++++++++---- ext/qrf/qrf-tester.c | 6 ++- ext/qrf/qrf.c | 9 ++-- ext/qrf/qrf.h | 2 +- main.mk | 34 ++++++++------ manifest | 25 +++++----- manifest.uuid | 2 +- src/tclsqlite.c | 73 ++++++++++++++++++++++------- test/tclsqlite.test | 2 +- tool/mkcombo.tcl | 106 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 229 insertions(+), 60 deletions(-) create mode 100644 tool/mkcombo.tcl diff --git a/Makefile.msc b/Makefile.msc index 3c075fac32..d5d1db9ab4 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1459,7 +1459,7 @@ SRC01 = \ $(TOP)\src\status.c \ $(TOP)\src\table.c \ $(TOP)\src\threads.c \ - $(TOP)\src\tclsqlite.c \ + tclsqlite-ex.c \ $(TOP)\src\tokenize.c \ $(TOP)\src\treeview.c \ $(TOP)\src\trigger.c \ @@ -2019,8 +2019,18 @@ sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-v sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(JIM_TCLSH) $(JIM_TCLSH) $(TOP)\tool\split-sqlite3c.tcl + +TCLSQLITEEX = \ + $(TOP)\ext\qrf\qrf.h \ + $(TOP)\ext\qrf\qrf.c \ + $(TOP)\src\tclsqlite.c + +tclsqlite-ex.c: $(TCLSQLITEEX) $(TOP)\tool\mkcombo.tcl $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\tool\mkcombo.tcl $(TCLSQLITEEX) -o $@ # <> +tclsqlite-ex.c: + # Rule to build the amalgamation # sqlite3.lo: $(SQLITE3C) @@ -2320,11 +2330,11 @@ whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR) window.lo: $(TOP)\src\window.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c -tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) - $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c +tclsqlite.lo: tclsqlite-ex.c $(HDR) $(SQLITE_TCL_DEP) + $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c tclsqlite-ex.c -tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) - $(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c +tclsqlite-shell.lo: tclsqlite-ex.c $(HDR) $(SQLITE_TCL_DEP) + $(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c tclsqlite-ex.c tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) $(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) @@ -2540,9 +2550,9 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_STRICT_SUBTYPE=1 TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) !IF $(USE_AMALGAMATION)==0 -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) +TESTFIXTURE_SRC = $(TESTSRC) tclsqlite-ex.c $(TESTFIXTURE_SRC0) !ELSE -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) +TESTFIXTURE_SRC = $(TESTSRC) tclsqlite-ex.c $(TESTFIXTURE_SRC1) !ENDIF !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 @@ -2677,14 +2687,14 @@ smoketest: $(TESTPROGS) shelltest: $(TESTPROGS) .\testfixture.exe $(TOP)\test\permutations.test shell -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP) +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) tclsqlite-ex.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP) $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl -DINCLUDE_SQLITE3_C $(TOP)\tool\sqlite3_analyzer.c.in > $@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) -sqltclsh.c: sqlite3.c $(TOP)\src\tclsqlite.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in +sqltclsh.c: sqlite3.c tclsqlite-ex.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in >sqltclsh.c sqltclsh.exe: sqltclsh.c $(SHELL_CORE_DEP) $(LIBRESOBJS) @@ -2697,7 +2707,7 @@ sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\exp CHECKER_DEPS =\ $(TOP)\tool\mkccode.tcl \ sqlite3.c \ - $(TOP)\src\tclsqlite.c \ + tclsqlite-ex.c \ $(TOP)\ext\repair\sqlite3_checker.tcl \ $(TOP)\ext\repair\checkindex.c \ $(TOP)\ext\repair\checkfreelist.c \ diff --git a/ext/qrf/qrf-tester.c b/ext/qrf/qrf-tester.c index 66aba5c6cd..8911882c86 100644 --- a/ext/qrf/qrf-tester.c +++ b/ext/qrf/qrf-tester.c @@ -71,7 +71,11 @@ static char *tempStrdup(char *zIn){ } /* Function used for writing to the console */ -static ssize_t testWriter(void *pContext, const unsigned char *p, size_t n){ +static sqlite3_int64 testWriter( + void *pContext, + const unsigned char *p, + sqlite3_int64 n +){ return fwrite(p,1,n,stdout); } diff --git a/ext/qrf/qrf.c b/ext/qrf/qrf.c index 2b4824b1c8..efcea72413 100644 --- a/ext/qrf/qrf.c +++ b/ext/qrf/qrf.c @@ -12,7 +12,9 @@ ** Implementation of the Result-Format or "qrf" utility library for SQLite. ** See the qrf.md documentation for additional information. */ +#ifndef SQLITE_QRF_H #include "qrf.h" +#endif #include #include #include @@ -219,7 +221,7 @@ static void qrfWrite(Qrf *p){ if( p->spec.xWrite && (n = sqlite3_str_length(p->pOut))>0 ){ p->spec.xWrite(p->spec.pWriteArg, (const unsigned char*)sqlite3_str_value(p->pOut), - (size_t)n); + (sqlite3_int64)n); sqlite3_str_reset(p->pOut); } } @@ -1059,7 +1061,7 @@ static void qrfColumnar(Qrf *p){ p->actualWidth = sqlite3_malloc64( sizeof(int)*nColumn ); if( p->actualWidth==0 ){ qrfOom(p); goto qrf_column_end; } for(i=0; ispec.nWidth && ispec.nWidth ? p->spec.aWidth[i] : 0; + w = ispec.nWidth ? p->spec.aWidth[i] : 0; if( w<0 ){ if( w==QRF_MINUS_ZERO ){ w = 0; } else{ w = -w; } @@ -1319,7 +1321,7 @@ static void qrfExplain(Qrf *p){ int *abYield = 0; /* abYield[iOp] is rue if opcode iOp is an OP_Yield */ int *aiIndent = 0; /* Indent the iOp-th opcode by aiIndent[iOp] */ i64 nAlloc = 0; /* Allocated size of aiIndent[], abYield */ - int nIndent; /* Number of entries in aiIndent[] */ + int nIndent = 0; /* Number of entries in aiIndent[] */ int iOp; /* Opcode number */ int i; /* Column loop counter */ @@ -1340,7 +1342,6 @@ static void qrfExplain(Qrf *p){ assert( 0==sqlite3_stricmp( sqlite3_column_name(p->pStmt, 3), "p2" ) ); for(iOp=0; SQLITE_ROW==sqlite3_step(p->pStmt); iOp++){ - int i; int iAddr = sqlite3_column_int(p->pStmt, 0); const char *zOp = (const char*)sqlite3_column_text(p->pStmt, 1); int p1 = sqlite3_column_int(p->pStmt, 2); diff --git a/ext/qrf/qrf.h b/ext/qrf/qrf.h index 4d8164d99f..208863f0d7 100644 --- a/ext/qrf/qrf.h +++ b/ext/qrf/qrf.h @@ -38,7 +38,7 @@ struct sqlite3_qrf_spec { const char *zTableName; /* Output table name */ const char *zNull; /* Rendering of NULL */ char *(*xRender)(void*,sqlite3_value*); /* Render a value */ - ssize_t (*xWrite)(void*,const unsigned char*,size_t); /* Write callback */ + sqlite3_int64 (*xWrite)(void*,const unsigned char*,sqlite3_int64); void *pRenderArg; /* First argument to the xRender callback */ void *pWriteArg; /* First argument to the xWrite callback */ char **pzOutput; /* Storage location for output string */ diff --git a/main.mk b/main.mk index 4182fd39d9..8dd10007a2 100644 --- a/main.mk +++ b/main.mk @@ -652,7 +652,7 @@ SRC = \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/sqliteLimit.h \ $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ + tclsqlite-ex.c \ $(TOP)/src/threads.c \ $(TOP)/src/tokenize.c \ $(TOP)/src/treeview.c \ @@ -1409,15 +1409,15 @@ whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) $(T.cc.sqlite) -c $(TOP)/src/window.c -tclsqlite.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) +tclsqlite.o: $(T.tcl.env.sh) tclsqlite-ex.c $(DEPS_OBJ_COMMON) $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC \ - -c $(TOP)/src/tclsqlite.c + -c tclsqlite-ex.c -tclsqlite-shell.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile.tcl) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $$TCL_INCLUDE_SPEC +tclsqlite-shell.o: $(T.tcl.env.sh) tclsqlite-ex.c $(DEPS_OBJ_COMMON) + $(T.compile.tcl) -DTCLSH -o $@ -c tclsqlite-ex.c $$TCL_INCLUDE_SPEC -tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile.tcl) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $$TCL_INCLUDE_SPEC +tclsqlite-stubs.o: $(T.tcl.env.sh) tclsqlite-ex.c $(DEPS_OBJ_COMMON) + $(T.compile.tcl) -DUSE_TCL_STUBS=1 -o $@ -c tclsqlite-ex.c $$TCL_INCLUDE_SPEC # # STATIC_TCLSQLITE3 = 1 to statically link tclsqlite3, else @@ -1661,11 +1661,19 @@ install-tcl-0 install-tcl-: install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl -tclsqlite3.c: sqlite3.c +TCLSQLITEEX = \ + $(TOP)/ext/qrf/qrf.h \ + $(TOP)/ext/qrf/qrf.c \ + $(TOP)/src/tclsqlite.c + +tclsqlite-ex.c: $(TCLSQLITEEX) $(TOP)/tool/mkcombo.tcl $(B.tclsh) + $(B.tclsh) $(TOP)/tool/mkcombo.tcl $(TCLSQLITEEX) -o $@ + +tclsqlite3.c: sqlite3.c tclsqlite-ex.c echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c - cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c + cat tclsqlite-ex.c >>tclsqlite3.c # # $(CFLAGS.tclextension) = CFLAGS for the tclextension* targets. @@ -1782,7 +1790,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 TESTFIXTURE_SRC0 = $(TESTSRC2) $(libsqlite3.LIB) TESTFIXTURE_SRC1 = sqlite3.c -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c +TESTFIXTURE_SRC = $(TESTSRC) tclsqlite-ex.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(T.exe): $(T.tcl.env.sh) has_tclsh85 $(TESTFIXTURE_SRC) @@ -1912,7 +1920,7 @@ shelltest: # sqlite3_analyzer.c.flags.0 = -DINCLUDE_SQLITE3_C=1 sqlite3_analyzer.c.flags.1 = -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ +sqlite3_analyzer.c: sqlite3.c tclsqlite-ex.c $(TOP)/tool/spaceanal.tcl \ $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in \ $(sqlite3_analyzer.c.flags.$(LINK_TOOLS_DYNAMICALLY)) \ @@ -1936,7 +1944,7 @@ sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c \ # can cause the $@ to link to an out-of-tree libsqlite3.so, which may # or may not fail or otherwise cause confusion. -sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ +sqltclsh.c: sqlite3.c tclsqlite-ex.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ $(TOP)/tool/sqltclsh.c.in $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c @@ -1957,7 +1965,7 @@ xbin: sqlite3_expert$(T.exe) CHECKER_DEPS =\ $(TOP)/tool/mkccode.tcl \ sqlite3.c \ - $(TOP)/src/tclsqlite.c \ + tclsqlite-ex.c \ $(TOP)/ext/repair/sqlite3_checker.tcl \ $(TOP)/ext/repair/checkindex.c \ $(TOP)/ext/repair/checkfreelist.c \ diff --git a/manifest b/manifest index c3194e7963..3c8f15a689 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sqrf\sbranch -D 2025-11-04T22:19:21.289 +C New\sbuild\sproduct\s"tclsqlite-ex.c"\sis\sthe\stclsqlite.c\sfile\swith\sQRF\sadded.\nThis\sis\snow\sused\swhereever\stclsqlite.c\swas\sused.\s\sHence\sQRF\sis\snow\sin\sthe\ntestfixture\sand\sin\sthe\stclextension.\s\sThe\ssqlite3\smethod\sis\s"format".\s\sThat\nmethod\sis\scurrently\sjust\sa\snon-functional\sstub. +D 2025-11-05T12:37:42.695 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc 8dd676302f3165984c046f81af14b6676a334418fa30255efaf439f8033042fa +F Makefile.msc 3eb1f6be1950c8a5535f0a6e17836fe18e57fb6ddb7a1a5985a3ec8f81deff97 F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7 F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -417,9 +417,9 @@ F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6 F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee F ext/qrf/README.md 1aa6f58a9442d329eff1d890dd33f565df636a47d8d0e878dbbf5c0ecba3b4c3 -F ext/qrf/qrf-tester.c ad66aeabe6a6c8e84a89e0d919702e8ba9216d6a2a42148116e659ab1967dff6 -F ext/qrf/qrf.c a9ac7d717486647534eaa87549befc440b1cb5da54f656c9b10bf3a3e13f9747 -F ext/qrf/qrf.h f2eb71d2d6b2b2bca68aac38a7b1a72ba55cecb93ea7673d38fdfe8898cbdc24 +F ext/qrf/qrf-tester.c 3a733b25a25ba7390cd3df055edd76ac72f488a9c5d9eb523a7508b0b8ac8900 +F ext/qrf/qrf.c 7c6a70ab5439a45b4d89f8121f1845a877f4e1d28889ed1fd92ce85ad60ed796 +F ext/qrf/qrf.h 701ddceb12e6b7957eeb4d77d057fddb66328840c189514b35daf27d1edb3a0e F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363 @@ -658,7 +658,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 609784b9e66d7b39ac74fa1d554a6dd0314347c9124ce3986d1df03f37814ffb +F main.mk 22c554873b933652b0ab89a729d90493687a799ac24e8f940c16461aa9091ea3 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -744,7 +744,7 @@ F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59 F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036 +F src/tclsqlite.c 0e88871f97e5d3116024804690e5f92db950411577c9042be8f02e4a22ba9d08 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a F src/test1.c f880ab766eeedf2c063662bd9538b923fd42c4341b7bfc2150a6d93ab8b9341c F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff @@ -1683,7 +1683,7 @@ F test/tabfunc01.test 56eeae736217204bb1d9f9ef38340d48058f809b64249217cf77ff4ba6 F test/table.test e87294bf1c80bfd7792142b84ab32ea5beb4f3f71e535d7fb263a6b2068377bf F test/tableapi.test e37c33e6be2276e3a96bb54b00eea7f321277115d10e5b30fdb52a112b432750 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 3f697424cfc1cdc9c076ec0cadb0e700f059400a3e3ce134b7d856fc9f880e1c +F test/tclsqlite.test 5d6c73bfe7006c85e2f7fb7db8638b521eb2043d5451aaacdac4851eab895443 F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -2116,6 +2116,7 @@ F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a19 F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a F tool/mkautoconfamal.sh 647dada5e34c466bef62a4408e1c99a7e5e1922805479dd57944f33f9803f2f8 F tool/mkccode.tcl c42a8f8cf78f92e83795d5447460dbce7aaf78a3bbf9082f1507dc71a3665f3c x +F tool/mkcombo.tcl 2a5189b219c4a495e1ff7fc980bd568d3cfb82ae9d50c84e77f7a161e96fc132 F tool/mkctimec.tcl 3fb5cad05922f5da61262cb6bcd5868a34e94a49ca8833ae2d7796e7df075576 x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a @@ -2171,8 +2172,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9644e2a8db4d97a85aa7660a1536894ab971abca52fb32f946c01de30eb40de3 cee2e2576f5e91911a019bff025ee6071850c0d75941e8746f10d57b56bd830a -R 7a237963e314e2fa86b8ba84b370f176 +P bed60e9be6d7f33c9f20dbb98bebdfaa7226a949a8e06691aea4d1e7c1af9507 +R a279d58d28b91b8b51c7e42c98a82ff3 U drh -Z 6a0f31fe761557cf0f7c976beb78fb3c +Z bc1252b29d805c5af10d1a6ff0d03432 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 97edf0a14d..f37ecb1864 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bed60e9be6d7f33c9f20dbb98bebdfaa7226a949a8e06691aea4d1e7c1af9507 +e08d21fe1365176f268f1dcca4048fb5ff043356e5817c8622b4ed9a1a5a58cf diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 02a4d84e46..a66d9f0077 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -124,6 +124,15 @@ /* Forward declaration */ typedef struct SqliteDb SqliteDb; +/* Add -DSQLITE_ENABLE_QRF_IN_TCL to add the Query Result Formatter (QRF) +** into the build of the TCL extension, when building using separate +** source files. The QRF is included automatically when building from +** the tclsqlite3.c amalgamation. +*/ +#if defined(SQLITE_ENABLE_QRF_IN_TCL) +#include "qrf.h" +#endif + /* ** New SQL functions can be created as TCL scripts. Each such function ** is described by an instance of the following structure. @@ -2035,6 +2044,23 @@ static void DbHookCmd( sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); } +/* +** Implementation of the "db format" command. +** +** Based on provided options, format the results of the SQL statement(s) +** provided into human-readable form using the Query Result Formatter (QRF) +** and return the resuling text. +*/ +static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ +#ifndef SQLITE_QRF_H + Tcl_SetResult(pDb->interp, "QRF not available in this build", TCL_VOLATILE); + return TCL_ERROR +#else + Tcl_SetResult(pDb->interp, "Not yet implemented", TCL_VOLATILE); + return TCL_OK; +#endif +} + /* ** The "sqlite" command below creates a new Tcl command for each ** connection it opens to an SQLite database. This routine is invoked @@ -2064,15 +2090,15 @@ static int SQLITE_TCLAPI DbObjCmd( "commit_hook", "complete", "config", "copy", "deserialize", "enable_load_extension", "errorcode", "erroroffset", "eval", - "exists", "function", "incrblob", - "interrupt", "last_insert_rowid", "nullvalue", - "onecolumn", "preupdate", "profile", - "progress", "rekey", "restore", - "rollback_hook", "serialize", "status", - "timeout", "total_changes", "trace", - "trace_v2", "transaction", "unlock_notify", - "update_hook", "version", "wal_hook", - 0 + "exists", "format", "function", + "incrblob", "interrupt", "last_insert_rowid", + "nullvalue", "onecolumn", "preupdate", + "profile", "progress", "rekey", + "restore", "rollback_hook", "serialize", + "status", "timeout", "total_changes", + "trace", "trace_v2", "transaction", + "unlock_notify", "update_hook", "version", + "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, @@ -2081,14 +2107,15 @@ static int SQLITE_TCLAPI DbObjCmd( DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_ERROROFFSET, DB_EVAL, - DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, - DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, - DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, - DB_PROGRESS, DB_REKEY, DB_RESTORE, - DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, - DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, - DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, + DB_EXISTS, DB_FORMAT, DB_FUNCTION, + DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, + DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE, + DB_PROFILE, DB_PROGRESS, DB_REKEY, + DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE, + DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, + DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, + DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, + DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2978,6 +3005,18 @@ deserialize_error: break; } + /* + ** $db format [OPTIONS] SQL + ** + ** Run the SQL statement(s) given as the final argument. Use the + ** Query Result Formatter extension of SQLite to format the output as + ** text and return that text. + */ + case DB_FORMAT: { + dbQrf(pDb, objc, objv); + break; + } + /* ** $db function NAME [OPTIONS] SCRIPT ** diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 5f373ea18a..6cababad33 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -42,7 +42,7 @@ do_test tcl-1.1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, erroroffset, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, erroroffset, eval, exists, format, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg diff --git a/tool/mkcombo.tcl b/tool/mkcombo.tcl new file mode 100644 index 0000000000..71368ec417 --- /dev/null +++ b/tool/mkcombo.tcl @@ -0,0 +1,106 @@ +#!/usr/bin/tclsh +# +# Use this script to combine multiple source code files into a single +# file. Example: +# +# tclsh mkcombo.tcl file1.c file2.c file3.c -o file123.c +# + +set help {Usage: tclsh mkcombo.tcl [OPTIONS] [FILELIST] + where OPTIONS is zero or more of the following with these effects: + --linemacros=? => Emit #line directives into output or not. (? = 1 or 0) + --o FILE => write to alternative output file named FILE + --help => See this. +} + +set linemacros 0 +set fname {} +set src [list] + + +for {set i 0} {$i<[llength $argv]} {incr i} { + set x [lindex $argv $i] + if {[regexp {^-?-linemacros(?:=([01]))?$} $x ma ulm]} { + if {$ulm == ""} {set ulm 1} + set linemacros $ulm + } elseif {[regexp {^-o$} $x]} { + incr i + if {$i==[llength $argv]} { + error "No argument following $x" + } + set fname [lindex $argv $i] + } elseif {[regexp {^-?-((help)|\?)$} $x]} { + puts $help + exit 0 + } elseif {[regexp {^-?-} $x]} { + error "unknown command-line option: $x" + } else { + lappend src $x + } +} + +# Open the output file and write a header comment at the beginning +# of the file. +# +if {![info exists fname]} { + set fname sqlite3.c + if {$enable_recover} { set fname sqlite3r.c } +} +set out [open $fname wb] + +# Return a string consisting of N "*" characters. +# +proc star N { + set r {} + for {set i 0} {$i<$N} {incr i} {append r *} + return $r +} + +# Force the output to use unix line endings, even on Windows. +fconfigure $out -translation binary +puts $out "/[star 78]" +puts $out {** The following is an amalgamation of these source code files:} +puts $out {**} +foreach s $src { + regsub {^.*/(src|ext)/} $s {\1/} s2 + puts $out "** $s2" +} +puts $out {**} +puts $out "[star 78]/" + +# Insert a comment into the code +# +proc section_comment {text} { + global out s78 + set n [string length $text] + set nstar [expr {60 - $n}] + puts $out "/************** $text [star $nstar]/" +} + +# Read the source file named $filename and write it into the +# sqlite3.c output file. The only transformation is the trimming +# of EOL whitespace. +# +proc copy_file_verbatim {filename} { + global out + set in [open $filename rb] + set tail [file tail $filename] + section_comment "Begin file $tail" + while {![eof $in]} { + set line [string trimright [gets $in]] + puts $out $line + } + section_comment "End of $tail" +} +set taillist "" +foreach file $src { + copy_file_verbatim $file + append taillist ", [file tail $file]" +} + +set taillist "End of the amalgamation of [string range $taillist 2 end]" +set n [string length $taillist] +set ns [expr {(75-$n)/2}] +if {$ns<3} {set ns 3} +puts $out "/[star $ns] $taillist [star $ns]/" +close $out -- 2.47.3